isset vs ??
В php7 стал доступен новый Null коалесцентный оператор ?? (Null coalescing operator - оператор объединения со значением null). Он возвращает левый операнд, если он не имеет значение null, или возвращается правый операнд. Так же возможны цепочки из нескольких значений.. Оператор очень интересный, давайте выяснять что быстрее isset vs ?? на типичных операциях. Сравнение с empty() vs isset() vs is_null() не делаю, поскольку знаю что isset быстрее, тесты можно в интернете найти.
Проверяем существование локальной переменной или глобальной
Результат этого теста, с объявлением глобально или нет, примерно одинаковы и показывают преимущество коалесцентного оператора. ($ix не задан..)
function f1(){ global $ix; $i=0;$x=0;while(++$i<LOOP)$x=isset($ix)?$ix:$i; } function f2(){ global $ix; $i=0;$x=0;while(++$i<LOOP)$x=$ix??$i; }Компьютер: (php 7.1.4)
№ | вызовов | время f1() | время f2() | победил | быстрее на | |
---|---|---|---|---|---|---|
1 | 1 000 000 | 0.026112 | 0.023609 | f2() | 0.002503 с. | 9.59 % |
2 | 1 000 000 | 0.025966 | 0.023624 | f2() | 0.002342 с. | 9.02 % |
3 | 1 000 000 | 0.025975 | 0.023551 | f2() | 0.002424 с. | 9.33 % |
4 | 1 000 000 | 0.033729 | 0.024999 | f2() | 0.008730 с. | 25.88 % |
5 | 1 000 000 | 0.026914 | 0.025144 | f2() | 0.001770 с. | 6.58 % |
6 | 1 000 000 | 0.030170 | 0.027798 | f2() | 0.002372 с. | 7.86 % |
7 | 1 000 000 | 0.025935 | 0.023677 | f2() | 0.002258 с. | 8.71 % |
8 | 1 000 000 | 0.026053 | 0.023748 | f2() | 0.002305 с. | 8.85 % |
9 | 1 000 000 | 0.026008 | 0.023705 | f2() | 0.002303 с. | 8.86 % |
Всего: 9 000 000 | 0.246862 | 0.219854 | f2() | 0.027008 с. | 10.94 % |
№ | вызовов | время f1() | время f2() | победил | быстрее на | |
---|---|---|---|---|---|---|
1 | 1 000 000 | 0.024104 | 0.019627 | f2() | 0.004477 с. | 18.57 % |
2 | 1 000 000 | 0.023860 | 0.019524 | f2() | 0.004336 с. | 18.17 % |
3 | 1 000 000 | 0.022508 | 0.019057 | f2() | 0.003451 с. | 15.33 % |
4 | 1 000 000 | 0.021760 | 0.019374 | f2() | 0.002386 с. | 10.96 % |
5 | 1 000 000 | 0.022738 | 0.019160 | f2() | 0.003578 с. | 15.74 % |
6 | 1 000 000 | 0.022233 | 0.019661 | f2() | 0.002572 с. | 11.57 % |
7 | 1 000 000 | 0.030133 | 0.019057 | f2() | 0.011076 с. | 36.76 % |
8 | 1 000 000 | 0.022909 | 0.020196 | f2() | 0.002713 с. | 11.84 % |
9 | 1 000 000 | 0.021634 | 0.018775 | f2() | 0.002859 с. | 13.22 % |
Всего: 9 000 000 | 0.211879 | 0.174431 | f2() | 0.037448 с. | 17.67 % |
Проверяем существование переменной в глобальном массиве GET
Эта задача типичная и представляет наибольший интерес. Также объявлял дополнительно массив $ix, $_GET и заполнял значениями - все разы isset побеждал примерно в том же соотношении что и в таблицах тестов ниже.
function f1(){ $i=0;$x=0;while(++$i<LOOP)$x=isset($_GET['ix'])?$_GET['ix']:$i; } function f2(){ $i=0;$x=0;while(++$i<LOOP)$x=$_GET['ix']??$i; }Компьютер: (php 7.1.4)
№ | вызовов | время f1() | время f2() | победил | быстрее на | |
---|---|---|---|---|---|---|
1 | 1 000 000 | 0.041406 | 0.044314 | f1() | 0.002908 с. | 6.56 % |
2 | 1 000 000 | 0.041443 | 0.044357 | f1() | 0.002914 с. | 6.57 % |
3 | 1 000 000 | 0.042932 | 0.045673 | f1() | 0.002741 с. | 6 % |
4 | 1 000 000 | 0.041758 | 0.044367 | f1() | 0.002609 с. | 5.88 % |
5 | 1 000 000 | 0.041260 | 0.045830 | f1() | 0.004570 с. | 9.97 % |
6 | 1 000 000 | 0.041734 | 0.045450 | f1() | 0.003716 с. | 8.18 % |
7 | 1 000 000 | 0.041063 | 0.044287 | f1() | 0.003224 с. | 7.28 % |
8 | 1 000 000 | 0.042666 | 0.045457 | f1() | 0.002791 с. | 6.14 % |
9 | 1 000 000 | 0.042563 | 0.045062 | f1() | 0.002499 с. | 5.55 % |
Всего: 9 000 000 | 0.376825 | 0.404798 | f1() | 0.027973 с. | 6.91 % |
№ | вызовов | время f1() | время f2() | победил | быстрее на | |
---|---|---|---|---|---|---|
1 | 1 000 000 | 0.034218 | 0.038240 | f1() | 0.004022 с. | 10.52 % |
2 | 1 000 000 | 0.034075 | 0.038606 | f1() | 0.004531 с. | 11.74 % |
3 | 1 000 000 | 0.033768 | 0.038209 | f1() | 0.004441 с. | 11.62 % |
4 | 1 000 000 | 0.034494 | 0.038290 | f1() | 0.003796 с. | 9.91 % |
5 | 1 000 000 | 0.034388 | 0.038023 | f1() | 0.003635 с. | 9.56 % |
6 | 1 000 000 | 0.034016 | 0.038039 | f1() | 0.004023 с. | 10.58 % |
7 | 1 000 000 | 0.033742 | 0.038750 | f1() | 0.005008 с. | 12.92 % |
8 | 1 000 000 | 0.035088 | 0.039027 | f1() | 0.003939 с. | 10.09 % |
9 | 1 000 000 | 0.033406 | 0.038658 | f1() | 0.005252 с. | 13.59 % |
Всего: 9 000 000 | 0.307195 | 0.345842 | f1() | 0.038647 с. | 11.17 % |
Эпилог
Удивительно, результат противоположен типичному поведению компилятора - текста больше, но исполнение isset всё равно быстрее с массивами. Внутри коалесцентрого оператора явно накодили лишнего. Есть смысл использовать для локальных переменных, но вот с типичной задачей проверки данных в массиве GET или просто в массиве - нет, а это самая частая задача для подобных операторов..
Из данного теста и предыдущего PHP 7 строгая типизация получается: в новых плюшках PHP7 нет необходимости, код можно оставить в состоянии версии php 5.4. Единственное радует, что PHP7 стал заметно производительнее и приближается к результатам с использованием файлового кэширования при помощи OPCache (компиляции в бинарники скриптов) на версиях php 5..