Почему === быстрее чем == в PHP?
Почему ===
быстрее, чем ==
в PHP?
10 ответов
Потому что оператор равенства ==
принудительно или временно преобразует тип данных, чтобы увидеть, равен ли он другому операнду, тогда как ===
(оператор идентификации) не нужно выполнять конвертацию, и, следовательно, выполняется меньше работы, что делает его быстрее.
===
не выполняет приведение типов, поэтому 0 == '0'
оценивает true
, но 0 === '0'
- для false
,
Есть две вещи для рассмотрения:
Если типы операндов отличаются, то
==
а также===
дают разные результаты. В этом случае скорость операторов не имеет значения; важно то, какой из них дает желаемый результат.Если типы операндов одинаковы, вы можете использовать либо
==
или же===
поскольку оба будут давать одинаковые результаты. В этом случае скорость обоих операторов практически одинакова. Это связано с тем, что ни один из операторов не выполняет преобразование типов.
Я сравнил скорость:
$a == $b
против$a === $b
- где
$a
а также$b
были случайными целыми числами [1, 100] - две переменные были сгенерированы и сравнены миллион раз
- тесты были проведены 10 раз
И вот результаты:
$a == $b $a === $b
--------- ---------
0.765770 0.762020
0.753041 0.825965
0.770631 0.783696
0.787824 0.781129
0.757506 0.796142
0.773537 0.796734
0.768171 0.767894
0.747850 0.777244
0.836462 0.826406
0.759361 0.773971
--------- ---------
0.772015 0.789120
Вы можете видеть, что скорость практически идентична.
Во-первых, === проверяет, имеют ли два аргумента один и тот же тип, поэтому число 1 и строка "1" завершаются неудачно при проверке типа до того, как будут выполнены какие-либо сравнения. С другой стороны, == сначала не проверяет тип, а затем преобразует оба аргумента в один и тот же тип, а затем выполняет сравнение.
Следовательно, === быстрее проверяет состояние ошибки
Я на самом деле не знаю, значительно ли это быстрее, но === в большинстве языков - это прямое сравнение типов, в то время как == попытается выполнить приведение типов, если необходимо / возможно, чтобы получить совпадение.
== влечет за собой большие издержки преобразования типов перед сравнением. === сначала проверяет тип, а затем продолжается без необходимости какого-либо преобразования типа.
Так как ===
не нужно приводить операнды к одному типу перед их сравнением.
Я сомневаюсь, что разница в скорости очень большая, хотя. При нормальных обстоятельствах вы должны использовать тот оператор, который имеет больше смысла.
В заключение === быстрее, потому что не преобразует тип данных, чтобы увидеть, если две переменные имеют одинаковое значение, но когда вам нужно увидеть, если две переменные имеют одинаковое значение, вы будете использовать ==, если не важно, какой тип являются переменными или === если важен также тип переменных.
Я обнаружил, что на самом деле между двумя операторами существует значительная разница в скорости. Ниже приведены результаты для php 8.0.0 RC5 и php 7.4.12, работающих в контейнере докеров. Проект размещен на github, поэтому каждый может ознакомиться с методологией. Отказ от ответственности: я создал инструмент.
$ php src/benchmark.php --custom --filter ~equal~
PHP benchmark
-------------------------------
platform : Linux x64
php version : 7.4.12
xdebug : off
memory limit : 128M
max execution : 0
time per iteration : 50ms
iterations : 100
-------------------------------
---------------------------------------------------
0 : == ===
mean : 394156 459015 +16.5%
median : 397448 461822 +16.2%
mode : 398154 458062 +15.0%
minimum : 313271 405692 +29.5%
maximum : 411157 480360 +16.8%
quartile 1 : 393222 454952 +15.7%
quartile 3 : 400881 466491 +16.4%
IQ range : 7659 11538 +50.7%
std deviation : 15593 11867 -23.9%
normality : 0.8% 0.8%
---------------------------------------------------
$ php src/benchmark.php --custom --filter ~equal~
PHP benchmark
-------------------------------
platform : Linux x64
php version : 8.0.0RC5
xdebug : off
memory limit : 128M
max execution : 0
time per iteration : 50ms
iterations : 100
-------------------------------
---------------------------------------------------
0 : == ===
mean : 405032 474768 +17.2%
median : 409226 477313 +16.6%
mode : 408421 479741 +17.5%
minimum : 311606 386509 +24.0%
maximum : 417895 491842 +17.7%
quartile 1 : 405740 473436 +16.7%
quartile 3 : 412677 483139 +17.1%
IQ range : 6937 9703 +39.9%
std deviation : 17501 15657 -10.5%
normality : 1.0% 1.0%
---------------------------------------------------
В php (код c) значение - это "класс", например:
class value
{
$int_;
$float_;
$string_;
$array_;
$object_;
}
Когда вы сравниваете $a == $b
а также $a
является int
типа, будет что-то вроде:
if ($a->int_ == $b->int_ || $a->int_ == (int) $b->float_ || $a->int_ == (int) $b->string_ || ...)
но string
'1'
не будет преобразован в код ascii 49
, это будет 1
.
Когда вы сравниваете $a === $b
а также $a
является int
типа, будет что-то вроде:
if ($a->int_ == $b->int_)
Быстрее следует измерять не только в прямом времени выполнения (в этом случае прямые тесты производительности практически ничтожны). Тем не менее, мне нужно было бы увидеть тест, включающий итерацию или рекурсию, чтобы действительно увидеть, есть ли существенная кумулятивная разница (при использовании в реалистическом контексте). Время тестирования и отладки, которое вы сэкономите при работе с крайними случаями, также должно быть значимым для вас.
Если результаты теста верны, то это должно быть проблемой компилятора,
Процессор будет делать все, что ему говорят, за такт
Если будет меньше, то будет быстрее
Дополнение:
Ну, на самом деле, если компилятор уже создал множество машинного кода для обработки, то, если он уже добавил миллионы вещей, чтобы справиться с тем, какой тип данных требует сравнения, то удаление одного "второстепенного" IF не изменит скорости сильно совсем.
Если кто-то все еще читает это, то мне интересно больше обсуждать.
Фил