Почему === быстрее чем == в PHP?

Почему === быстрее, чем == в PHP?

10 ответов

Решение

Потому что оператор равенства == принудительно или временно преобразует тип данных, чтобы увидеть, равен ли он другому операнду, тогда как === (оператор идентификации) не нужно выполнять конвертацию, и, следовательно, выполняется меньше работы, что делает его быстрее.

=== не выполняет приведение типов, поэтому 0 == '0' оценивает true, но 0 === '0' - для false,

Есть две вещи для рассмотрения:

  1. Если типы операндов отличаются, то == а также === дают разные результаты. В этом случае скорость операторов не имеет значения; важно то, какой из них дает желаемый результат.

  2. Если типы операндов одинаковы, вы можете использовать либо == или же === поскольку оба будут давать одинаковые результаты. В этом случае скорость обоих операторов практически одинакова. Это связано с тем, что ни один из операторов не выполняет преобразование типов.

Я сравнил скорость:

  • $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 не изменит скорости сильно совсем.

Если кто-то все еще читает это, то мне интересно больше обсуждать.

Фил

Другие вопросы по тегам