За последние 24 часа нас посетили 20939 программистов и 1106 роботов. Сейчас ищут 438 программистов ...

Кружок любопытных извращенцев :)

Тема в разделе "Прочие вопросы по PHP", создана пользователем Psih, 9 июн 2009.

  1. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    count(*) обойдет по скорости count(id) при условии правильного типа таблицы.
    Индексы хранятся отдельно. Намек ясен?
    Выборка поочередно списка столбцов или захват всех - скажется оно по производительности не в пользу второго.
     
  2. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    не помню, было ль или нет такое: тест статических методов
    Код (Text):
    1. PHP 5.2.4 (cgi-fcgi) (built: Aug 30 2007 07:06:30)
    2. Copyright (c) 1997-2007 The PHP Group
    3. Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    4.     with the ionCube PHP Loader v3.1.32, Copyright (c) 2002-2007, by ionCube Ltd., and
    5.     with Xdebug v2.0.5, Copyright (c) 2002-2008, by Derick Rethans
    PHP:
    1. <?php
    2. $ts = microtime(true);
    3. /*
    4. float(0.822402954102)
    5. class StaticClass
    6. {
    7.     public static function doSmth($arg)
    8.     {
    9.         return 'doSmth' . $arg;
    10.     }
    11. }
    12.  
    13. for ($i = 0; $i < 100000; $i++) {
    14.     $c = StaticClass::doSmth(': c');
    15. }
    16. */
    17.  
    18. /*
    19. float(0.770346879959)
    20. class NonStaticClass
    21. {
    22.     public function doSmth($arg)
    23.     {
    24.         return 'doSmth' . $arg;
    25.     }
    26. }
    27. $obj = new NonStaticClass();
    28.  
    29. for ($i = 0; $i < 100000; $i++) {
    30.     $c = $obj->doSmth(': c');
    31. }
    32. */
    33. /*
    34. float(1.23220682144)
    35. class NonStaticClassCalledStatic
    36. {
    37.     public function doSmth($arg)
    38.     {
    39.         return 'doSmth' . $arg;
    40.     }
    41. }
    42.  
    43. for ($i = 0; $i < 100000; $i++) {
    44.     $c = NonStaticClassCalledStatic::doSmth(': c');
    45. }
    46. */
    47.  
    48. var_dump(microtime(true) - $ts);
    49.  
     
  3. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Koc
    было, но не помню на какой версии PHP.
     
  4. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    песок ложкой меряете, на производительности обычно сказывается тупой запрос, который не использует индексы, вызывает full scan, file sort, temporary table, вот это да, сказывается, а милисекунды на разницу подсчета столбцов - х[я пугаюсь неуместного использование матов. Luge]я, тем более, что если место не критичное, то при добавлении 1 поля, придется переписывать еще и код
     
  5. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Желая присоединиться к клубу извращенцев могу сказать, что сам давно гоняю РНР ещё с четвертой версии и не перестаю удивляться. Я написал специальный API для проверки скорости работы разных алгоритмов, этот API выступает в роли непредвзятого эксперта: все тесты выполняются независимо друг от друга с большой частотой и исключает время, затраченное на прокрутку циклов.

    Тесты можно гонять в двух режимах: учитывая время, затрачиваемое РНР на загрузку и парсинг скрипта и без оного.

    Пример работы тестера:
    http://scriptumplus.ru/test.html

    Пример самого теста:
    Код (Text):
    1. ;число итераций
    2. iterations = 100
    3. ;краткое описание теста
    4. description = "Чтение файла в массив"
    5. ;подробное описание теста
    6. text = "Нужно получить массив из файла путем разбивки его построчно. Минус функции file - внутри массива окажутся мусорные \n и \r."
    7. ;РНР-файл, который нужно выполнить до теста, но не учитывать время его выполнения (обычно там просто <?php)
    8. head = "head.php"
    9. ;перечисление самих тестов
    10. test[] = "$a=file($file);"
    11. test_info[] = "file"
    12. test[] = "explode(\"\n\", file_get_contents($file));"
    13. test_info[] = "file_get_contents+explode"
    Пока в разработке и в поиске интересных тестов. Может быть кто-то присоединится, API прост донельзя.
     
  6. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Что-то с циклами напутали. Ничего не делать в цикле нежелательно - это нереальные тесты. Хотя пых уже новый, будет интересно погонять на разных версиях.
    [​IMG]
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    вывод неверный =)
     
  8. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Пока я маюсь с уменьшением дисперсии в тестах, всё равно можно сделать правильный вывод. Редко когда используется РНР без оптимизаторов, а по сему однозначно можно сказать что одинарные кавычки будут быстрее, хотя и в "чистом" РНР двойные могут обгонять одинарные.

    С другой стороны от версии к версии РНР преподносит такие сюрпризы, что не перестаю удивляться по сей день.
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    а по тесту - одинаково =)

    кстати я читал тесты где длинные имена переменных ниибово так все тормозили. хз может исправили...
     
  10. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Тест с длинными именами меня обескуражил. Во-первых в РНр без акселератора однобуквенная переменная медленнее двубуквенной (видать хэш-таблицы в пыхе особенные). А включение акслератора показало, что переменная из 60 символов быстрее чем из 6-и.

    Кстати у меня там второй тест, которые показывает, что двойные кавычки быстрее одинарных:)
     
  11. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
  12. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Обновился
    http://scriptumplus.ru/test.html

    Выводы всё же такие:

    - строки в РНР теперь можно использовать как удобно, без разницы какие кавычки, так как разница невелика
    - большая длина переменной несильно замедляет парсинг
    - foreach ныне дрючит всех по части чтения массива
    - count и sizeof и правда алиасы
    - file_get_contents дрючит всех если надо открыть файл целиком
    - лучше использовать explode вместо file, так как это позволяет сразу избавиться от символов \n
    - обратный цикл и правда быстрее прямого на 30%, но с усложнением тела цикла разница сходит на нет

    А ещё погрешность тестов была под 300%, пока не начал запускать их каждый внутри своего интерпретатора, предварительно погоняв незначащие 6 тестов.
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    ышо давай
     
  14. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    Проверял работу ГСЧ, кроме прочего породился еще один тест:
    (rand vs. mt_rand)
    PHP:
    1. <?php
    2.     function ASD ($arr)
    3.     {
    4.         $sum = array_sum($arr);
    5.         $avgx = $sum/count($arr);
    6.         $narr = array();
    7.         for($i=0; $i<count($arr); $i++)
    8.         {
    9.             $narr[$i] = pow(($arr[$i]-$avgx),2);
    10.         }
    11.         $D = (1/count($arr))*array_sum($narr);
    12.         echo "Disp ".$D."\r\n";
    13.         echo "ASD ".sqrt($D)."\r\n";
    14.     }
    15.  
    16.     $iters = 100000;
    17.     preg_match("/\.(\d+) /", microtime(), $res);
    18.     mt_srand($res[1]);
    19.     //$a = mt_rand(0,100);
    20.     $arr = array();
    21.     $i = $iters;
    22.     $mctimeS = microtime();
    23.     while(--$i)
    24.     {
    25.         $arr[$i] = mt_rand(0,100);
    26.         $i--;
    27.     }
    28.     list($mctF1,$mctF2) = explode(" ", microtime());
    29.     list($mctS1,$mctS2) = explode(" ", $mctimeS);
    30.     echo "Generation time: ".($mctF1-$mctS1+$mctF2-$mctS2);
    31.     echo " for iter: ".(($mctF1-$mctS1+$mctF2-$mctS2)/$iters)." s\n";
    32.     ASD($arr);
    33.  
    34.     preg_match("/\.(\d+) /", microtime(), $res);
    35.     srand($res[1]);
    36.     //$a = mt_rand(0,100);
    37.     $arr = array();
    38.     $i = $iters;
    39.     $mctimeS = microtime();
    40.     while(--$i)
    41.     {
    42.         $arr[$i] = rand(0,100);
    43.     }
    44.     list($mctF1,$mctF2) = explode(" ", microtime());
    45.     list($mctS1,$mctS2) = explode(" ", $mctimeS);
    46.     echo "Generation time: ".($mctF1-$mctS1+$mctF2-$mctS2);
    47.     echo " for iter: ".(($mctF1-$mctS1+$mctF2-$mctS2)/$iters)." s\n";
    48.     ASD($arr);
    49. ?>
    Код (Text):
    1. Generation time: 0.09532904624939 for iter: 9.532904624939E-7 s
    2. Disp 850.28889175313
    3. ASD 29.159713506019
    4. Generation time: 0.089111089706421 for iter: 8.9111089706421E-7 s
    5. Disp 846.04118214301
    6. ASD 29.086787071504
    Если не кривить душой, то у обоих методов распределение дискретное распределенное, но вот качество у mt_rand значительно выше - еще ни разу в практических задачах не наткнулся на кольцевое замыкание у mt ни под линухой, ни под виндой. У обычного rand такое короткое кольцо, что натыкаешься на него снова и снова. Сравнивал 1/mt_rand(0,mt_getrandmax()) с ГПСЧ Парка-Миллера (кольцо 2,147,483,646 значений для float), был приятно удивлен, распеределение у обоих дискретное распределенное, покрытие равномерное, а даже с делением mt_rand был капельку быстрее.

    Вывод: используйте mt_rand. По скорости на 8% медленнее, а длинна кольца как у взрослых ГПСЧ.

    Если нужен супер/мега правильный ГСЧ, используйте mcrypt_dev_rand (преимущества только с юниксоподобными системами, т.к. под виндой эмуляция)

    А вообще было бы неплохо, когда крутятся тесты, вычислять СКО, потому что если по результатам в 1 сигму помещается общее время выполнения всего теста, то это херня, а не тест. Переведу: если разброс больше времени выполнения, то тестируем скорость записи букв.

    udp: Поправил косяки, извиняюсь
     
  15. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Нормальное распределение у ГПСЧ??? Я в ужасе.
     
  16. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
  17. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    всегда думал, что rand выдает равномерное распределение и нормальное нужно лишь в редких случаях.

    Ps ссылка слишком длинная
     
  18. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Магическое быстродействие
    Всего PHP имеет 13 магических методов. Нет особого смысла тестировать такие специфичные методы, как __sleep и __invoke, т.к. они незаменимы, а вот применения __get и __set в 90% случаев можно избежать, немного усложнив код. Стоит ли овчинка выделки?

    __set()
    Код (PHP):
    1. <?
    2. class A
    3. {
    4. }
    5. $a = new A;
    6. for ($i=0; $i<100000; $i++) {
    7.      $a->$i = 1;
    8. }[/php]
    9. [code]Выполнено за 0.1124 сек.
    PHP:
    1. <?
    2. class A
    3. {
    4.      function __set($n, $v) {
    5.           $this->$n = $v;
    6.      }
    7. }
    8. $a = new A;
    9. for ($i=0; $i<100000; $i++) {
    10.      $a->$i = 1;
    11. } [/code]
    12. [code]Выполнено за 0.3297 сек.[/code]
    13. Магический метод в 3 раза медленнее прямого обращения к свойству. Самое время сравнить с обычным методом:
    14. [code=php]<?
    15. class A
    16. {
    17.      function set($n, $v) {
    18.           $this->$n = $v;
    19.      }
    20. }
    21. $a = new A;
    22. for ($i=0; $i<100000; $i++) {
    23.      $a->set($i, 1);
    24. } [/code]
    25. [code]Выполнено за 0.2417 сек.[/code]
    26. Обычный метод вдвое медленнее прямого обращения и на 1/3 быстрее "магии".
    27. Как сформулировать "__set аж в три раза медленнее" или "прямое обращение всего в три раза медленнее" решайте сами.
    28.  
    29. [b]__get()[/b]
    30. [code=php]<?
    31. class A
    32. {
    33.      function __get($n) {
    34.           return null;
    35.      }
    36. }
    37. $a = new A;
    38. for ($i=0; $i<100000; $i++) {
    39.      $a->$i;
    40. } [/code]
    41. [code]Выполнено за 0.1955 сек.[/code]
    42. ничотак результат, но что будет без магии?
    43. [code=php]<?
    44. class A
    45. {
    46. }
    47. $a = new A;
    48. for ($i=0; $i<100000; $i++) {
    49.      $a->$i;
    50. }
    51.  [/code]
    52. [code]Выполнено за 3.2733 сек.[/code]
    53. Результат предсказуем чуть менее, чем полностью - php вывалил миллион нотисов, что  [url=http://www.php.ru/forum/viewtopic.php?p=162482#162482]замедлило выполнение операции в 9 раз[/url].
    54. Поэтому напишм реально альтернативную конструкцию:
    55. [code=php]<?
    56. class A
    57. {
    58. }
    59. $a = new A;
    60. for ($i=0; $i<100000; $i++) {
    61.      if (isset($a->$i)) {
    62.           $a->$i;
    63.      } else {}
    64. } [/code]
    65. [code]Выполнено за 0.0686 сек..[/code]
    66. ну чтож, опять втрое быстрее. Но вам придется городить такую конструкцию везде, где можно было бы обойтись методом __get. Если использовать немагический метод get, то время выполнения оказывается примерно посередине.
    67.  
    68. Плюшки, которые даёт магия перед прямым обращением:
    69. - выполнение функции
    70. - доступ к приватным свойствам
    71. - возможность избежать лишней проверки
    72.  
    73. Плюшки магии в сравнении с обычным методом:
    74. - способ обращения как к свойству
    75.  
    76. Каждая "плюшка" стоит 50% производительности =)
     
  19. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Тест на __get плохой. Сделайте в классе property и тестируйте доступ к ней, а не скорость работы isset
     
  20. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    но __get выполняется только если свойство не объявлено. Как тогда их адекватно сравнить?
     
  21. Pran

    Pran Активный пользователь

    С нами с:
    15 янв 2011
    Сообщения:
    39
    Симпатии:
    0
    ob_start() ... ob_get_clean() вместо конкатенации (vers 2.0)

    Однажды обнаружил, что конструкция вида ob_start() ... echo ... ob_get_clean() выполняется быстрее вместо множественной конкатенации:

    Код (Text):
    1.  
    2. <?php
    3.     // Инициализация счётчиков.
    4.     $exOne = $exTwo = 0;
    5.  
    6.     for ($k = 1000; --$k;)
    7.     {
    8.         ##
    9.         ## Example I: concatenation
    10.         ##
    11.  
    12.         $start = microtime(true);
    13.  
    14.         $tmp = null;
    15.  
    16.         for ($m = 1000; --$m;)
    17.         {
    18.             $tmp .= '-i' . '-t' . '-e' . '-r' . '-a';
    19.         }
    20.  
    21.         $exOne += (microtime(true) - $start);
    22.  
    23.         ##
    24.         ## Example II: buffered output
    25.         ##
    26.  
    27.         $start = microtime(true);
    28.  
    29.         ob_start();
    30.  
    31.         for ($m = 1000; --$m;)
    32.         {
    33.             echo '-i', '-t', '-e', '-r', '-a';
    34.         }
    35.  
    36.         $tmp = ob_get_clean();
    37.  
    38.         $exTwo += (microtime(true) - $start);
    39.     }
    40. ?>
    41.  
    42. <table>
    43.     <tr>
    44.         <td>Average of concatenation</td>
    45.         <td><?= sprintf('%0.6f с', $exOne / 1000) ?></td>
    46.     </tr>
    47.     <tr>
    48.         <td>Average of buffering</td>
    49.         <td><?= sprintf('%0.6f с', $exTwo / 1000) ?></td>
    50.     </tr>
    51. </table>
    Результат выполнения (PHP 5.3.10):
    Код (Text):
    1. Average of concatenation 0.000509 с
    2. Average of buffering 0.000278 с
    Результат выполнения (PHP 5.4.3):
    Код (Text):
    1. Average of concatenation 0.000391 с
    2. Average of buffering 0.000322 с
    Однако, в случае малой конкатенации:
    Код (Text):
    1.  
    2. <?php
    3.     // Инициализация счётчиков.
    4.     $exOne = $exTwo = 0;
    5.  
    6.     for ($k = 1000; --$k;)
    7.     {
    8.         ##
    9.         ## Example I: concatenation
    10.         ##
    11.  
    12.         $start = microtime(true);
    13.  
    14.         $tmp = null;
    15.  
    16.         for ($m = 1000; --$m;)
    17.         {
    18.             $tmp .= '-i';
    19.         }
    20.  
    21.         $exOne += (microtime(true) - $start);
    22.  
    23.         ##
    24.         ## Example II: buffered output
    25.         ##
    26.  
    27.         $start = microtime(true);
    28.  
    29.         ob_start();
    30.  
    31.         for ($m = 1000; --$m;)
    32.         {
    33.             echo '-i';
    34.         }
    35.  
    36.         $tmp = ob_get_clean();
    37.  
    38.         $exTwo += (microtime(true) - $start);
    39.     }
    40. ?>
    41.  
    42. <table>
    43.     <tr>
    44.         <td>Average of concatenation</td>
    45.         <td><?= sprintf('%0.6f с', $exOne / 1000) ?></td>
    46.     </tr>
    47.     <tr>
    48.         <td>Average of buffering</td>
    49.         <td><?= sprintf('%0.6f с', $exTwo / 1000) ?></td>
    50.     </tr>
    51. </table>
    Результат выполнения (PHP 5.3.10):
    Код (Text):
    1.  
    2. Average of concatenation 0.000095 с
    3. Average of buffering 0.000101 с
    Результат выполнения (PHP 5.4.3):
    Код (Text):
    1.  
    2. Average of concatenation 0.000088 с
    3. Average of buffering 0.000115 с
    Имел место баг циклов (единая переменная $i), исправил 20.04.2012.
     
  22. Pran

    Pran Активный пользователь

    С нами с:
    15 янв 2011
    Сообщения:
    39
    Симпатии:
    0
    Способ адекватного сравнения __get

    Заметил одну особенность в PHP 5.3: если свойство объявлено как null, обращение к индексу null[$key] даст null. Вот соответствующий тест:

    Код (Text):
    1.  
    2. <?php
    3.  
    4.     class Sample {
    5.  
    6.         public $prop = null;
    7.  
    8.         public function __get($name)
    9.         {
    10.             return $this->prop[$name];
    11.         }
    12.     }
    13.  
    14.     // Инициализация счётчика.
    15.     $exOne = $exTwo = 0;
    16.  
    17.     $a = new Sample;
    18.  
    19.     for ($i = 1000; --$i;)
    20.     {
    21.         ##
    22.         ## Example I: __get access.
    23.         ##
    24.  
    25.         $start = microtime(true);
    26.  
    27.         for ($m = 10000; --$m;)
    28.         {
    29.             $a->$i;
    30.         }
    31.  
    32.         $exOne += (microtime(true) - $start);
    33.  
    34.         ##
    35.         ## Example II: direct access.
    36.         ##
    37.  
    38.         $start = microtime(true);
    39.  
    40.         for ($m = 10000; --$m;)
    41.         {
    42.             $a->prop[$i];
    43.         }
    44.  
    45.         $exTwo += (microtime(true) - $start);
    46.     }
    47.    
    48. ?>
    49.  
    50. <table>
    51.     <tr>
    52.         <td>Average of __get access is </td>
    53.         <td><?= sprintf('%0.6f sec', $exOne / 1000) ?></td>
    54.     </tr>
    55.     <tr>
    56.         <td>Average of direct access is </td>
    57.         <td><?= sprintf('%0.6f sec', $exTwo / 1000) ?></td>
    58.     </tr>
    59. </table>
    Результат выполнения (PHP 5.3.10):
    Код (Text):
    1.  
    2. Average of __get access is 0.006844 sec
    3. Average of direct access is 0.001566 sec
    Результат выполнения (PHP 5.4.3):
    Код (Text):
    1.  
    2. Average of __get access is 0.006132 sec
    3. Average of direct access is 0.000856 sec
     
  23. XCoder

    XCoder Активный пользователь

    С нами с:
    28 ноя 2011
    Сообщения:
    48
    Симпатии:
    0
    Интересует сравнение времени исполнения операции include на системе с SSD в сравнении с HDD, если у кого есть возможность - буду весьма благодарен информации!
     
  24. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    акселераторы для этого есть. прям ваще быстрее некуда будет.
     
  25. XCoder

    XCoder Активный пользователь

    С нами с:
    28 ноя 2011
    Сообщения:
    48
    Симпатии:
    0