with.php: Код (Text): <?php $a = []; if (!isset($a['c'])) { $a['c'] = 1; } else { $a['c']++; } without.php: Код (Text): <?php $a = []; if (!isset($a['c'])) $a['c'] = 1; else $a['c']++; Код (Text): $ php -d vld.active=1 -d vld.execute=0 -f with.php Код (Text): line # * op fetch ext return operands --------------------------------------------------------------------------------- 3 0 > EXT_STMT 1 INIT_ARRAY ~0 2 ASSIGN !0, ~0 5 3 EXT_STMT 4 ISSET_ISEMPTY_DIM_OBJ 2000000 ~2 !0, 'c' 5 BOOL_NOT ~3 ~2 6 > JMPZ ~3, ->11 6 7 > EXT_STMT 8 ASSIGN_DIM !0, 'c' 9 OP_DATA 1, $5 7 10 > JMP ->15 8 11 > EXT_STMT 12 FETCH_DIM_RW $6 !0, 'c' 13 POST_INC ~7 $6 14 FREE ~7 10 15 > > RETURN 1 Код (Text): $ php -d vld.active=1 -d vld.execute=0 -f without.php Код (Text): line # * op fetch ext return operands --------------------------------------------------------------------------------- 3 0 > EXT_STMT 1 INIT_ARRAY ~0 2 ASSIGN !0, ~0 5 3 EXT_STMT 4 ISSET_ISEMPTY_DIM_OBJ 2000000 ~2 !0, 'c' 5 BOOL_NOT ~3 ~2 6 6 > JMPZ ~3, ->10 7 > ASSIGN_DIM !0, 'c' 8 OP_DATA 1, $5 9 > JMP ->13 8 10 > FETCH_DIM_RW $6 !0, 'c' 11 POST_INC ~7 $6 12 FREE ~7 10 13 > > RETURN 1 Блоки в скобках заключаются в EXT_STMT. При исполнении приходится выполнять не отдельную инструкцию, а блок со входом и выходом из него. Добавлено спустя 13 минут 44 секунды: А, нет, я протупил. Это XDebug добавляет. С отключенным XDebug всё практически идентично: Код (Text): line # * op fetch ext return operands --------------------------------------------------------------------------------- 3 0 > INIT_ARRAY ~0 1 ASSIGN !0, ~0 5 2 ISSET_ISEMPTY_DIM_OBJ 2000000 ~2 !0, 'c' 3 BOOL_NOT ~3 ~2 4 > JMPZ ~3, ->8 6 5 > ASSIGN_DIM !0, 'c' 6 OP_DATA 1, $5 7 7 > JMP ->11 8 8 > FETCH_DIM_RW $6 !0, 'c' 9 POST_INC ~7 $6 10 FREE ~7 11 11 > > RETURN 1 И скорости сравниваются. У вас xdebug был включён?
о, васяц! без xdebug варианты if и if {} выравниваются, тернарник по прежнему медленный - теперь вдвое более медленный, чем if
r2d2, не замечаю: Код (Text): $A = []; $B = []; for ($i = 0; $i < 10000; $i++) { $A[] = \mt_rand(0, 1) ? true : false; } $mt1 = \microtime(true); foreach ($A as $item) { $B[] = $item ? 1 : 2; } $mt1 = \microtime(true) - $mt1; $B = []; $mt2 = \microtime(true); foreach ($A as $item) { if ($item) { $B[] = 1; } else { $B[] = 2; } } $mt2 = \microtime(true) - $mt2; echo 'tern / if: '.($mt1 / $mt2).\PHP_EOL; В районе единицы где-то колбасит. Чуть-чуть if побыстрее.
Ага. Никогда не задумывался, подключён он или нет, ибо не пользуюсь. "И на старуху бывает проруха" Действительно, если эту хрень отключить совсем, то скоростя почти сравниваются и всё шустрее ворочается. Если с ним было (см. viewtopic.php?f=2&t=45785#p364972) Код (Text): N 10 0.5810 | 100% 0.4653 | 125% 0.4038 | 144% то без него в 2 раза с гаком быстрее Код (Text): N 10 N 10 0.1635 | 100% 0.1543 | 106% 0.1553 | 105%
ой, а я и забыл про xdebug. привык к нему. и в голову не пришло, что он может влиять, а ведь это естественно!
vasa_c, ты почему-то отступил от начального примера. мы как-раз видим, что незначительные изменения могут иметь неожиданный эффект по производительности. а ты сильно другие выражения начал тестировать. фу на тебя! Добавлено спустя 4 минуты 30 секунд: Код (PHP): <?php $a = array(); $iter = 1000000; $start = microtime(true); for ($i = 0; $i < $iter; $i++) { (!isset($a['c'])) ? $a : $a; } $end = microtime(true); echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n"; $start = microtime(true); for ($i = 0; $i < $iter; $i++) { if (!isset($a['c'])) { $a; } else { $a; } } $end = microtime(true); echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n"; $start = microtime(true); for ($i = 0; $i < $iter; $i++) { if (!isset($a['c'])) $a; else $a; } $end = microtime(true); echo number_format(($end - $start) * 1000, 3, '.', ' ') . "\n"; тестирую в консоли with xdebug: 586.032 469.844 405.300 without xdebug: 293.271 129.300 130.346
Chushkin, да, к слову, я тебе тоже без иксдебага скидывал результаты И ты напрасно не глянул влияние кэша и оптимизатора не время работы, кстати. Продублирую сюда, пусть народ сам делает выводы: Без кэша: Код (Text): N 1 0.8167 | 100% 0.6683 | 122% 0.6461 | 126% N 2 0.7697 | 100% 0.6516 | 118% 0.6602 | 117% N 3 0.7346 | 100% 0.6486 | 113% 0.6555 | 112% N 4 0.7137 | 100% 0.6505 | 110% 0.6686 | 107% N 5 0.7047 | 100% 0.6510 | 108% 0.6652 | 106% N 6 0.7098 | 100% 0.6506 | 109% 0.6643 | 107% N 7 0.7035 | 100% 0.6564 | 107% 0.6606 | 106% N 8 0.6964 | 100% 0.6541 | 106% 0.6746 | 103% N 9 0.6908 | 100% 0.6528 | 106% 0.6713 | 103% N 10 0.6902 | 100% 0.6552 | 105% 0.6690 | 103% Avg: 0.5957 | 105% 0.6082 | 103% Холодный опкэш + оптимизация(генерация кэша с оптимизатором всегда занимает времени гораздо больше, чем простая интерпретация): Код (Text): N 1 2.1486 | 100% 1.0608 | 203% 0.3684 | 583% N 2 1.2602 | 100% 0.7080 | 178% 0.3655 | 345% N 3 0.9654 | 100% 0.6875 | 140% 0.3924 | 246% N 4 0.8193 | 100% 0.6524 | 126% 0.3949 | 207% N 5 0.7582 | 100% 0.6261 | 121% 0.4218 | 180% N 6 0.7016 | 100% 0.5881 | 119% 0.4496 | 156% N 7 0.6594 | 100% 0.5678 | 116% 0.4468 | 148% N 8 0.6242 | 100% 0.5435 | 115% 0.4370 | 143% N 9 0.5970 | 100% 0.5230 | 114% 0.4473 | 133% N 10 0.5938 | 100% 0.5044 | 118% 0.4339 | 137% Avg: 0.4585 | 118% 0.3944 | 137% Прогретый оптимизированный опкэш: Код (Text): N 1 0.6441 | 100% 0.6251 | 103% 0.5995 | 107% N 2 0.6289 | 100% 0.6170 | 102% 0.6024 | 104% N 3 0.6302 | 100% 0.6334 | 100% 0.6015 | 105% N 4 0.6269 | 100% 0.6292 | 100% 0.6000 | 104% N 5 0.6261 | 100% 0.6246 | 100% 0.6023 | 104% N 6 0.6276 | 100% 0.6238 | 101% 0.6005 | 105% N 7 0.6265 | 100% 0.6206 | 101% 0.6010 | 104% N 8 0.6258 | 100% 0.6215 | 101% 0.6037 | 104% N 9 0.6221 | 100% 0.6197 | 100% 0.6057 | 103% N 10 0.6202 | 100% 0.6195 | 100% 0.6052 | 102% Avg: 0.5632 | 100% 0.5502 | 102% Холодный опкэш без оптимизации: Код (Text): N 1 0.6625 | 100% 0.6507 | 102% 0.6572 | 101% N 2 0.6592 | 100% 0.6849 | 96% 0.6861 | 96% N 3 0.6775 | 100% 0.6901 | 98% 0.6893 | 98% N 4 0.6895 | 100% 0.6871 | 100% 0.6966 | 99% N 5 0.6901 | 100% 0.6917 | 100% 0.6947 | 99% N 6 0.6850 | 100% 0.6838 | 100% 0.6919 | 99% N 7 0.6829 | 100% 0.6803 | 100% 0.6911 | 99% N 8 0.6852 | 100% 0.6829 | 100% 0.6908 | 99% N 9 0.6825 | 100% 0.6790 | 101% 0.6877 | 99% N 10 0.6832 | 100% 0.6776 | 101% 0.6913 | 99% Avg: 0.6160 | 101% 0.6284 | 99% Прогретый кэш без оптимизации: Код (Text): N 1 0.6404 | 100% 0.6278 | 102% 0.6273 | 102% N 2 0.6394 | 100% 0.6339 | 101% 0.6281 | 102% N 3 0.6638 | 100% 0.6309 | 105% 0.6335 | 105% N 4 0.6604 | 100% 0.6313 | 105% 0.6382 | 103% N 5 0.6559 | 100% 0.6305 | 104% 0.6430 | 102% N 6 0.6520 | 100% 0.6298 | 104% 0.6392 | 102% N 7 0.6491 | 100% 0.6306 | 103% 0.6374 | 102% N 8 0.6477 | 100% 0.6368 | 102% 0.6404 | 101% N 9 0.6467 | 100% 0.6385 | 101% 0.6394 | 101% N 10 0.6474 | 100% 0.6387 | 101% 0.6380 | 101% Avg: 0.5806 | 101% 0.5800 | 101%
Поглядим опкоды Код (Text): $u = true; $x = 0; $x = $u ? 1 : 2; Код (Text): line # * op fetch ext return operands --------------------------------------------------------------------------------- 3 0 > ASSIGN !0, true 4 1 ASSIGN !1, 0 6 2 > JMPZ !0, ->5 3 > QM_ASSIGN ~2 1 4 > JMP ->6 5 > QM_ASSIGN ~2 2 6 > ASSIGN !1, ~2 8 7 > RETURN 1 Код (Text): $u = true; $x = 0; if ($u) { $x = 1; } else { $x = 2; } Код (Text): line # * op fetch ext return operands --------------------------------------------------------------------------------- 3 0 > ASSIGN !0, true 4 1 ASSIGN !1, 0 6 2 > JMPZ !0, ->5 7 3 > ASSIGN !1, 1 8 4 > JMP ->6 9 5 > ASSIGN !1, 2 12 6 > > RETURN 1 if сразу присваивает значение (ASSIGN), тернарник накапливает промежуточное (QM_ASSIGN). Добавлено спустя 1 минуту 7 секунд: Хм. Это форум меняет в ссылке php.net на php.ru?
Я видел. Судя по твоим результатам, ни опкеш ни оптимизатор практически не влияют на этот тест (в пределах флуктуаций).
Не, ну ясно, что в такой ситуации, +900000% прироста выжать физически не от куда Но какие-то спички все равно видны. Флуктуация-не-флуктуация, а в пределах каждого теста показатели отличаются от показателей другого. Ты сам знаешь, что у тебя в тестах все усреднено, чтобы как раз погрешности такие сгляживать. Тут же в каждой выборке время-таки меняется, пусть и несущественно, если смотреть с точки зрения пользы. В любом случае, как ни крути, сам по себе if практически бесплатен для железки независимо от формы записи. То же и тернарника касается.
PHP странная штука - при каждом запуске отдного и того же теста время будет разное. Результаты разнятся до 20%. Поэтому и говорю " в пределах флуктуации".