За последние 24 часа нас посетили 19133 программиста и 1639 роботов. Сейчас ищут 889 программистов ...

Сравнение if() и if()

Тема в разделе "Прочие вопросы по PHP", создана пользователем Chushkin, 22 сен 2013.

  1. vasa_c

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

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    with.php:
    Код (Text):
    1.  
    2. <?php
    3.  
    4. $a = [];
    5.  
    6. if (!isset($a['c'])) {
    7.     $a['c'] = 1;
    8. } else {
    9.     $a['c']++;
    10. }
    without.php:
    Код (Text):
    1.  
    2. <?php
    3.  
    4. $a = [];
    5.  
    6. if (!isset($a['c']))
    7.     $a['c'] = 1;
    8. else
    9.     $a['c']++;
    Код (Text):
    1. $ php -d vld.active=1 -d vld.execute=0 -f with.php
    Код (Text):
    1.  
    2. line     # *  op                           fetch          ext  return  operands
    3. ---------------------------------------------------------------------------------
    4.    3     0  >   EXT_STMT                                                
    5.          1      INIT_ARRAY                                       ~0      
    6.          2      ASSIGN                                                   !0, ~0
    7.    5     3      EXT_STMT                                                
    8.          4      ISSET_ISEMPTY_DIM_OBJ                       2000000  ~2      !0, 'c'
    9.          5      BOOL_NOT                                         ~3      ~2
    10.          6    > JMPZ                                                     ~3, ->11
    11.    6     7  >   EXT_STMT                                                
    12.          8      ASSIGN_DIM                                               !0, 'c'
    13.          9      OP_DATA                                                  1, $5
    14.    7    10    > JMP                                                      ->15
    15.    8    11  >   EXT_STMT                                                
    16.         12      FETCH_DIM_RW                                     $6      !0, 'c'
    17.         13      POST_INC                                         ~7      $6
    18.         14      FREE                                                     ~7
    19.   10    15  > > RETURN                                                   1
    Код (Text):
    1. $ php -d vld.active=1 -d vld.execute=0 -f without.php
    Код (Text):
    1.  
    2. line     # *  op                           fetch          ext  return  operands
    3. ---------------------------------------------------------------------------------
    4.    3     0  >   EXT_STMT                                                
    5.          1      INIT_ARRAY                                       ~0      
    6.          2      ASSIGN                                                   !0, ~0
    7.    5     3      EXT_STMT                                                
    8.          4      ISSET_ISEMPTY_DIM_OBJ                       2000000  ~2      !0, 'c'
    9.          5      BOOL_NOT                                         ~3      ~2
    10.    6     6    > JMPZ                                                     ~3, ->10
    11.          7  >   ASSIGN_DIM                                               !0, 'c'
    12.          8      OP_DATA                                                  1, $5
    13.          9    > JMP                                                      ->13
    14.    8    10  >   FETCH_DIM_RW                                     $6      !0, 'c'
    15.         11      POST_INC                                         ~7      $6
    16.         12      FREE                                                     ~7
    17.   10    13  > > RETURN                                                   1
    Блоки в скобках заключаются в EXT_STMT. При исполнении приходится выполнять не отдельную инструкцию, а блок со входом и выходом из него.

    Добавлено спустя 13 минут 44 секунды:
    А, нет, я протупил. Это XDebug добавляет. С отключенным XDebug всё практически идентично:
    Код (Text):
    1.  
    2. line     # *  op                           fetch          ext  return  operands
    3. ---------------------------------------------------------------------------------
    4.    3     0  >   INIT_ARRAY                                       ~0      
    5.          1      ASSIGN                                                   !0, ~0
    6.    5     2      ISSET_ISEMPTY_DIM_OBJ                       2000000  ~2      !0, 'c'
    7.          3      BOOL_NOT                                         ~3      ~2
    8.          4    > JMPZ                                                     ~3, ->8
    9.    6     5  >   ASSIGN_DIM                                               !0, 'c'
    10.          6      OP_DATA                                                  1, $5
    11.    7     7    > JMP                                                      ->11
    12.    8     8  >   FETCH_DIM_RW                                     $6      !0, 'c'
    13.          9      POST_INC                                         ~7      $6
    14.         10      FREE                                                     ~7
    15.   11    11  > > RETURN                                                   1
    И скорости сравниваются.
    У вас xdebug был включён?
     
  2. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    о, васяц! без xdebug варианты if и if {} выравниваются, тернарник по прежнему медленный - теперь вдвое более медленный, чем if
     
  3. vasa_c

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

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    r2d2, не замечаю:
    Код (Text):
    1.  
    2. $A = [];
    3. $B = [];
    4.  
    5. for ($i = 0; $i < 10000; $i++) {
    6.     $A[] = \mt_rand(0, 1) ? true : false;
    7. }
    8.  
    9.  
    10. $mt1 = \microtime(true);
    11. foreach ($A as $item) {
    12.     $B[] = $item ? 1 : 2;
    13. }
    14. $mt1 = \microtime(true) - $mt1;
    15.  
    16. $B = [];
    17. $mt2 = \microtime(true);
    18. foreach ($A as $item) {
    19.     if ($item) {
    20.         $B[] = 1;
    21.     } else {
    22.         $B[] = 2;
    23.     }
    24. }
    25. $mt2 = \microtime(true) - $mt2;
    26.  
    27. echo 'tern / if: '.($mt1 / $mt2).\PHP_EOL;
    В районе единицы где-то колбасит. Чуть-чуть if побыстрее.
     
  4. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Ага. Никогда не задумывался, подключён он или нет, ибо не пользуюсь.
    "И на старуху бывает проруха" :(

    Действительно, если эту хрень отключить совсем, то скоростя почти сравниваются и всё шустрее ворочается.
    Если с ним было (см. viewtopic.php?f=2&t=45785#p364972)
    Код (Text):
    1. N 10
    2. 0.5810 | 100%
    3. 0.4653 | 125%
    4. 0.4038 | 144%
    то без него в 2 раза с гаком быстрее
    Код (Text):
    1. N 10
    2. N 10
    3. 0.1635 | 100%
    4. 0.1543 | 106%
    5. 0.1553 | 105%
     
  5. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ой, а я и забыл про xdebug. привык к нему. и в голову не пришло, что он может влиять, а ведь это естественно!
     
  6. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    vasa_c, ты почему-то отступил от начального примера. мы как-раз видим, что незначительные изменения могут иметь неожиданный эффект по производительности. а ты сильно другие выражения начал тестировать.
    фу на тебя!

    Добавлено спустя 4 минуты 30 секунд:
    Код (PHP):
    1. <?php
    2.  
    3.  
    4. $a = array();
    5. $iter = 1000000;
    6.  
    7. $start = microtime(true);
    8. for ($i = 0; $i < $iter; $i++) {
    9.   (!isset($a['c'])) ? $a : $a;
    10. }
    11. $end = microtime(true);
    12. echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n"; 
    13.  
    14. $start = microtime(true);
    15. for ($i = 0; $i < $iter; $i++) {
    16.   if (!isset($a['c'])) {
    17.     $a;
    18.   } else {
    19.     $a;
    20.   }
    21. }
    22. $end = microtime(true);
    23. echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n";
    24.  
    25. $start = microtime(true);
    26. for ($i = 0; $i < $iter; $i++) {
    27.   if (!isset($a['c'])) 
    28.     $a;
    29.   else 
    30.     $a;
    31. }
    32. $end = microtime(true);
    33. echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n"; 
    тестирую в консоли

    with xdebug:
    586.032
    469.844
    405.300

    without xdebug:
    293.271
    129.300
    130.346
     
  7. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Chushkin, да, к слову, я тебе тоже без иксдебага скидывал результаты:)
    И ты напрасно не глянул влияние кэша и оптимизатора не время работы, кстати.
    Продублирую сюда, пусть народ сам делает выводы:

    Без кэша:
    Код (Text):
    1. N 1
    2. 0.8167 | 100%
    3. 0.6683 | 122%
    4. 0.6461 | 126%
    5. N 2
    6. 0.7697 | 100%
    7. 0.6516 | 118%
    8. 0.6602 | 117%
    9. N 3
    10. 0.7346 | 100%
    11. 0.6486 | 113%
    12. 0.6555 | 112%
    13. N 4
    14. 0.7137 | 100%
    15. 0.6505 | 110%
    16. 0.6686 | 107%
    17. N 5
    18. 0.7047 | 100%
    19. 0.6510 | 108%
    20. 0.6652 | 106%
    21. N 6
    22. 0.7098 | 100%
    23. 0.6506 | 109%
    24. 0.6643 | 107%
    25. N 7
    26. 0.7035 | 100%
    27. 0.6564 | 107%
    28. 0.6606 | 106%
    29. N 8
    30. 0.6964 | 100%
    31. 0.6541 | 106%
    32. 0.6746 | 103%
    33. N 9
    34. 0.6908 | 100%
    35. 0.6528 | 106%
    36. 0.6713 | 103%
    37. N 10
    38. 0.6902 | 100%
    39. 0.6552 | 105%
    40. 0.6690 | 103%
    41. Avg:
    42. 0.5957 | 105%
    43. 0.6082 | 103%
    Холодный опкэш + оптимизация(генерация кэша с оптимизатором всегда занимает времени гораздо больше, чем простая интерпретация):
    Код (Text):
    1. N 1
    2. 2.1486 | 100%
    3. 1.0608 | 203%
    4. 0.3684 | 583%
    5. N 2
    6. 1.2602 | 100%
    7. 0.7080 | 178%
    8. 0.3655 | 345%
    9. N 3
    10. 0.9654 | 100%
    11. 0.6875 | 140%
    12. 0.3924 | 246%
    13. N 4
    14. 0.8193 | 100%
    15. 0.6524 | 126%
    16. 0.3949 | 207%
    17. N 5
    18. 0.7582 | 100%
    19. 0.6261 | 121%
    20. 0.4218 | 180%
    21. N 6
    22. 0.7016 | 100%
    23. 0.5881 | 119%
    24. 0.4496 | 156%
    25. N 7
    26. 0.6594 | 100%
    27. 0.5678 | 116%
    28. 0.4468 | 148%
    29. N 8
    30. 0.6242 | 100%
    31. 0.5435 | 115%
    32. 0.4370 | 143%
    33. N 9
    34. 0.5970 | 100%
    35. 0.5230 | 114%
    36. 0.4473 | 133%
    37. N 10
    38. 0.5938 | 100%
    39. 0.5044 | 118%
    40. 0.4339 | 137%
    41. Avg:
    42. 0.4585 | 118%
    43. 0.3944 | 137%
    Прогретый оптимизированный опкэш:
    Код (Text):
    1. N 1
    2. 0.6441 | 100%
    3. 0.6251 | 103%
    4. 0.5995 | 107%
    5. N 2
    6. 0.6289 | 100%
    7. 0.6170 | 102%
    8. 0.6024 | 104%
    9. N 3
    10. 0.6302 | 100%
    11. 0.6334 | 100%
    12. 0.6015 | 105%
    13. N 4
    14. 0.6269 | 100%
    15. 0.6292 | 100%
    16. 0.6000 | 104%
    17. N 5
    18. 0.6261 | 100%
    19. 0.6246 | 100%
    20. 0.6023 | 104%
    21. N 6
    22. 0.6276 | 100%
    23. 0.6238 | 101%
    24. 0.6005 | 105%
    25. N 7
    26. 0.6265 | 100%
    27. 0.6206 | 101%
    28. 0.6010 | 104%
    29. N 8
    30. 0.6258 | 100%
    31. 0.6215 | 101%
    32. 0.6037 | 104%
    33. N 9
    34. 0.6221 | 100%
    35. 0.6197 | 100%
    36. 0.6057 | 103%
    37. N 10
    38. 0.6202 | 100%
    39. 0.6195 | 100%
    40. 0.6052 | 102%
    41. Avg:
    42. 0.5632 | 100%
    43. 0.5502 | 102%
    Холодный опкэш без оптимизации:
    Код (Text):
    1. N 1
    2. 0.6625 | 100%
    3. 0.6507 | 102%
    4. 0.6572 | 101%
    5. N 2
    6. 0.6592 | 100%
    7. 0.6849 | 96%
    8. 0.6861 | 96%
    9. N 3
    10. 0.6775 | 100%
    11. 0.6901 | 98%
    12. 0.6893 | 98%
    13. N 4
    14. 0.6895 | 100%
    15. 0.6871 | 100%
    16. 0.6966 | 99%
    17. N 5
    18. 0.6901 | 100%
    19. 0.6917 | 100%
    20. 0.6947 | 99%
    21. N 6
    22. 0.6850 | 100%
    23. 0.6838 | 100%
    24. 0.6919 | 99%
    25. N 7
    26. 0.6829 | 100%
    27. 0.6803 | 100%
    28. 0.6911 | 99%
    29. N 8
    30. 0.6852 | 100%
    31. 0.6829 | 100%
    32. 0.6908 | 99%
    33. N 9
    34. 0.6825 | 100%
    35. 0.6790 | 101%
    36. 0.6877 | 99%
    37. N 10
    38. 0.6832 | 100%
    39. 0.6776 | 101%
    40. 0.6913 | 99%
    41. Avg:
    42. 0.6160 | 101%
    43. 0.6284 | 99%
    Прогретый кэш без оптимизации:
    Код (Text):
    1. N 1
    2. 0.6404 | 100%
    3. 0.6278 | 102%
    4. 0.6273 | 102%
    5. N 2
    6. 0.6394 | 100%
    7. 0.6339 | 101%
    8. 0.6281 | 102%
    9. N 3
    10. 0.6638 | 100%
    11. 0.6309 | 105%
    12. 0.6335 | 105%
    13. N 4
    14. 0.6604 | 100%
    15. 0.6313 | 105%
    16. 0.6382 | 103%
    17. N 5
    18. 0.6559 | 100%
    19. 0.6305 | 104%
    20. 0.6430 | 102%
    21. N 6
    22. 0.6520 | 100%
    23. 0.6298 | 104%
    24. 0.6392 | 102%
    25. N 7
    26. 0.6491 | 100%
    27. 0.6306 | 103%
    28. 0.6374 | 102%
    29. N 8
    30. 0.6477 | 100%
    31. 0.6368 | 102%
    32. 0.6404 | 101%
    33. N 9
    34. 0.6467 | 100%
    35. 0.6385 | 101%
    36. 0.6394 | 101%
    37. N 10
    38. 0.6474 | 100%
    39. 0.6387 | 101%
    40. 0.6380 | 101%
    41. Avg:
    42. 0.5806 | 101%
    43. 0.5800 | 101%
     
  8. vasa_c

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

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Поглядим опкоды

    Код (Text):
    1.  
    2. $u = true;
    3. $x = 0;
    4.  
    5. $x = $u ? 1 : 2;
    Код (Text):
    1.  
    2. line     # *  op                           fetch          ext  return  operands
    3. ---------------------------------------------------------------------------------
    4.    3     0  >   ASSIGN                                                   !0, true
    5.    4     1      ASSIGN                                                   !1, 0
    6.    6     2    > JMPZ                                                     !0, ->5
    7.          3  >   QM_ASSIGN                                        ~2      1
    8.          4    > JMP                                                      ->6
    9.          5  >   QM_ASSIGN                                        ~2      2
    10.          6  >   ASSIGN                                                   !1, ~2
    11.    8     7    > RETURN                                                   1
    Код (Text):
    1.  
    2. $u = true;
    3. $x = 0;
    4.  
    5. if ($u) {
    6.     $x = 1;
    7. } else {
    8.     $x = 2;
    9. }
    Код (Text):
    1.  
    2. line     # *  op                           fetch          ext  return  operands
    3. ---------------------------------------------------------------------------------
    4.    3     0  >   ASSIGN                                                   !0, true
    5.    4     1      ASSIGN                                                   !1, 0
    6.    6     2    > JMPZ                                                     !0, ->5
    7.    7     3  >   ASSIGN                                                   !1, 1
    8.    8     4    > JMP                                                      ->6
    9.    9     5  >   ASSIGN                                                   !1, 2
    10.   12     6  > > RETURN                                                   1
    if сразу присваивает значение (ASSIGN), тернарник накапливает промежуточное (QM_ASSIGN).

    Добавлено спустя 1 минуту 7 секунд:
    Хм. Это форум меняет в ссылке php.net на php.ru?
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    да, он та еще стерва, кормящая парсер.
     
  10. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Я видел. Судя по твоим результатам, ни опкеш ни оптимизатор практически не влияют на этот тест (в пределах флуктуаций).
     
  11. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ну куда уж тут влиять-то, ребят.
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Не, ну ясно, что в такой ситуации, +900000% прироста выжать физически не от куда :)
    Но какие-то спички все равно видны. Флуктуация-не-флуктуация, а в пределах каждого теста показатели отличаются от показателей другого. Ты сам знаешь, что у тебя в тестах все усреднено, чтобы как раз погрешности такие сгляживать. Тут же в каждой выборке время-таки меняется, пусть и несущественно, если смотреть с точки зрения пользы.

    В любом случае, как ни крути, сам по себе if практически бесплатен для железки независимо от формы записи. То же и тернарника касается.
     
  13. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    PHP странная штука - при каждом запуске отдного и того же теста время будет разное. Результаты разнятся до 20%. Поэтому и говорю " в пределах флуктуации".
     
  14. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65