Сравнение производительности методов выбора элементов из массива 25.08.2010

Во время профилирования php кода часто «всплывают» функции вызываемые несколько тысяч раз за время выполнения одного сценария. Такие функции необходимо жестко оптимизировать, так как потерянная миллисекунда выливается в итоге в секунду. Одной из частых ошибок встречаемых мной в различных программах является получения элемента массива, наличие которого неизвестно. Тут распространены несколько методов:

  1.  
  2. // Method 1
  3. $a = @$array['asdfsdfsdfsdf'];
  4. // Method 2
  5. $anull;
  6. if (isset($array['asdfsdfsdfsdf'])){
  7.     $a$array['asdfsdfsdfsdf'];
  8. }
  9. // Method 3
  10. $anull;
  11. if (array_key_exists('asdfsdfsdfsdf'$array)){
  12.     $a$array['asdfsdfsdfsdf'];
  13. }
  14.  

Я провел небольшое тестирование с целью выяснить, какой метод самый быстрый.

Для этого я написал вот такой тест

  1.  
  2. <?php
  3. $emptyarray();
  4.  
  5. $tmicrotime(true);
  6. for($i = 1; $i <= 1000000$i++){
  7.     $a = @ $empty[$i];
  8. }
  9. print("@ — " . (microtime(true) — $t) . PHP_EOL) ;
  10.  
  11.  
  12. $tmicrotime(true);
  13. for($i = 1; $i <= 1000000$i++){
  14.     if (isset($empty[$i])){
  15.         $a$empty[$i];
  16.     } else {
  17.         $anull;
  18.     }
  19. }
  20.  
  21. print("isset (if expand) — " . (microtime(true) — $t) . PHP_EOL) ;
  22.  
  23.  
  24. $tmicrotime(true);
  25. for($i = 1; $i <= 1000000$i++){
  26.     $a = isset($empty[$i]) ? $empty[$i]null;
  27. }
  28.  
  29. print("isset (?:) — " . (microtime(true) — $t) . PHP_EOL) ;
  30.  
  31. $tmicrotime(true);
  32. for($i = 1; $i <= 1000000$i++){
  33.     if (array_key_exists($i$empty)){
  34.         $a$empty[$i];
  35.     } else {
  36.         $anull;
  37.     }
  38. }
  39.  
  40. print("array_key_exists — " . (microtime(true) — $t) . PHP_EOL) ;
  41.  

Результаты такие:

@   2.9017329216003
isset (if expand)   0.57358312606812
isset (?:)   0.51982712745667
array_key_exists   3.554811000824

На первом месте по скорости конструкция isset в записанная в краткой форме условия. Не очень читабельно, зато быстро. На втором все тот же isset, только в развернутой форме

На третьем месте блокирование ошибок с помощью @ с почти что 6-кратным отставанием. Очень плохой способ, так как помимо всего в error_handler будут прилетать сообщения об ошибках, которые он должен будет обрабатывать, что снизит производительность еще более

На последнем месте array_key_exists, его использование имеет смысл только в одном случае, если нужно достоверно убедиться, что элемент с таким индексом существует, даже если в нем записан null


, ,


Похожие статьи


Добавить комментарий