ifбыстрее, чемswitch;echoбыстрее, чемprint;- явная проверка на (не)нулевое значение медленнее, чем неявная.
- константные выражения, которые могут быть вычислены на этапе компиляции, не вычисляются;
- PHP не умеет удалять неиспользуемый код на этапе компиляции.
Продолжим.
Конкатенация или переменные внутри строки?
| Конкатенация | Переменные внутри строки | |
|---|---|---|
| Код |
[-]
View Code PHP
<?php
$tpl = "str2"; $text = 'str1 ' . $tpl . " str3\n"; echo $text; ?> |
[-]
View Code PHP
<?php
$tpl = "str2"; $text = "str1 {$tpl} str3\n"; echo $text; ?> |
| Результат |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $tpl, 'str2' 3 1 CONCAT ~1 'str1 ', $tpl 2 CONCAT ~2 ~1, ' str3\n' 3 ASSIGN $text, ~2 4 4 ECHO $text 6 5 RETURN 1 6* ZEND_HANDLE_EXCEPTION |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $tpl, 'str2' 3 1 INIT_STRING ~1 2 ADD_STRING ~1 ~1, 'str1 ' 3 ADD_VAR ~1 ~1, $tpl 4 ADD_STRING ~1 ~1, ' str3\n' 5 ASSIGN $text, ~1 4 6 ECHO $text 6 7 RETURN 1 8* ZEND_HANDLE_EXCEPTION |
Вывод: конкатенация быстрее, и, как показал тест (путём замены echo $text; на echo memory_get_usage();), потребляет меньше памяти.
Цикл со счётчиком: while или for?
for |
while |
|
|---|---|---|
| Код |
[-]
View Code PHP
<?php
for ($i=0; $i<1000; ++$i) { } ?> |
[-]
View Code PHP
<?php
$i = 0; while ($i<1000) { ++$i; } ?> |
| Результат |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $i, 0 1 IS_SMALLER ~1 $i, 1000 2 JMPZNZ 5 ~1, ->6 3 PRE_INC $i 4 JMP ->1 3 5 JMP ->3 7 6 RETURN 1 7* ZEND_HANDLE_EXCEPTION |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $i, 0 3 1 IS_SMALLER ~1 $i, 1000 2 JMPZ ~1, ->5 4 3 PRE_INC !0 5 4 JMP ->1 9 5 RETURN 1 6* ZEND_HANDLE_EXCEPTION |
Вывод: хотя цикл while выглядит многословнее (по крайней мере, длиннее), он, на удивление, оказывается короче полностью аналогичного цикла for. Таким образом, не всегда более короткий код оказывается более эффективным. При этом так как второй вариант короче (в плане количества опкодов), он потребляет меньше памяти.
Пустая строка или NULL?
| Пустая строка | null |
|
|---|---|---|
| Код |
[-]
View Code PHP
<?php
$a = ""; echo memory_get_usage(); ?> |
[-]
View Code PHP
<?php
$a = NULL; echo memory_get_usage(); ?> |
| Результат | 106,336 | 106,224 |
Вывод: использование пустых значений «сложных» типов (строки, массивы, объекты) ведёт к повышенному потреблению памяти. Использование NULL — самый оптимальный вариант.
is_null() или строгая проверка на NULL?
is_null |
Строгое соответствие | |
|---|---|---|
| Код |
[-]
View Code PHP
<?php
$a = 0; if (is_null($a)) { } ?> |
[-]
View Code PHP
<?php
$a = 0; if ($a === NULL) { } ?> |
| Результат |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $a, 0 3 1 SEND_VAR $a 2 DO_FCALL 1 'is_null' 3 JMPZ $1, ->5 4 4 JMP ->5 6 5 RETURN 1 6* ZEND_HANDLE_EXCEPTION |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ASSIGN $a, 0 3 1 IS_IDENTICAL ~1 $a, null 2 JMPZ ~1, ->4 4 3 JMP ->4 6 4 RETURN 1 5* ZEND_HANDLE_EXCEPTION |
Вывод: проверка на строгое равенство NULL работает быстрее, в том числе из-за отсутствия необходимости вызова функции.
echo: конкатенация или запятые?
| Конкатенация | Запятые | |
|---|---|---|
| Код |
[-]
View Code PHP
<?php
echo 'Memory ' . 'usage ' . 'is ' . memory_get_usage() . "\n"; ?> |
[-]
View Code PHP
<?php
echo 'Memory ', 'usage ', 'is ', memory_get_usage(), "\n"; ?> |
| Результат |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 CONCAT ~0 'Memory ', 'usage ' 1 CONCAT ~1 ~0, 'is ' 2 DO_FCALL 0 'memory_get_usage' 3 CONCAT ~3 ~1, $2 4 CONCAT ~4 ~3, '\n' 5 ECHO ~4 3 6 RETURN 1 7* ZEND_HANDLE_EXCEPTION |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 ECHO 'Memory ' 1 ECHO 'usage ' 2 ECHO 'is ' 3 DO_FCALL 0 'memory_get_usage' 4 ECHO $0 5 ECHO '\n' 3 6 RETURN 1 7* ZEND_HANDLE_EXCEPTION |
| Memory usage is 106192 | Memory usage is 106184 |
Выводы: в очередной раз менее читабельный метод оказался лучшим — на этот раз в плане потребления памяти. И, как видим, PHP не догадался даже объединить строки вместе.
Что быстрее: статический или динамический метод?
| Динамический метод | Статический метод | |
|---|---|---|
| Код |
[-]
View Code PHP
<?php
class A { public function test() {} } $a = new A; $a->test(); ?> |
[-]
View Code PHP
<?php
class A { public static function test() {} } $a = new A; A::test(); ?> |
| Результат |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 NOP 6 1 ZEND_FETCH_CLASS :1 'A' 2 NEW $2 :1 3 DO_FCALL_BY_NAME 0 4 ASSIGN $a, $2 7 5 ZEND_INIT_METHOD_CALL $5 $a, 'test' 6 DO_FCALL_BY_NAME 0 8 7 RETURN 1 8* ZEND_HANDLE_EXCEPTION |
[-]
View Code Text
line # op fetch ext return operands
------------------------------------------------------------------------------- 2 0 NOP 6 1 ZEND_FETCH_CLASS :1 'A' 2 NEW $2 :1 3 DO_FCALL_BY_NAME 0 4 ASSIGN $a, $2 7 5 ZEND_FETCH_CLASS :5 'A' 6 ZEND_INIT_STATIC_METHOD_CALL null, 'test' 7 DO_FCALL_BY_NAME 0 8 8 RETURN 1 9* ZEND_HANDLE_EXCEPTION |
Выводы: при прочих равных условиях, вызов статического метода на один опкод длиннее вызова динамического метода. Таким образом, если делать все методы класса, которые не используют $this, статическими, это приведёт к потреблению памяти.
Спички спичками, но сколько таких спичек экономится в мало-мальски сложном скрипте (таком, как WordPress). Пусть результат от одной сэкономленной спички ничтожно мал, но помноженный на количество таких потенциальных спичек во всём коде, становится весьма и весьма ощутимым, особенно на слабом железе.
Меня зовут
Completely agree, your article is amazing, thanks for sharing with us!!!this was really useful
Сенкь ю ))
А я все равно считаю, что больший приоритет надо отдавать читабельности кода, но в пределах разумного (всячески избегать рекурсии например). А оптимизацией пусть занимаются разработчики компиляторов
А зачем вы перед вызовом статического метода объект создавали?
Мда, ошибочка вышла
Спасибо
А что с тестами?
P.s: Извиняюсь за некропостинг : )
Leave a comment below if you dare
If by accident you see this form, please do not use it; use the form below this instead.