БлогNot. PHP: количество раз, которое нужное значение встречается в массиве

PHP: количество раз, которое нужное значение встречается в массиве

Вроде бы мелочь, а неприятно - функции, позволяющей определить, сколько раз встречается в массиве нужное значение, в стандартных не обнаружил. Зато есть array_count_values, которая подсчитает встречаемость всех значений, и есть array_filter, способная сделать с массива нужный "срез".

Соответственно, если не заботиться о ресурсах и писать в типично-современном стиле, задачу можно сделать как минимум двумя способами :) Третий способ - написать классический код с поэлементным сканированием массива и проверкой элементов на равенство нужному значению.

Несложный тест на массиве из миллиона элементов показывает, что array_count_values лучше всего, классический код в 2-2,5 раза хуже, а вот array_filter в данном случае - очень медленно. Подумайте, почему. Обратите внимание, что array_count_value1 без указания global $val; работать с безымянной callback-функцией не будет (встроенная функция фильтрации элементов не возьмёт $val из параметров array_count_value1). Такие уж у PHP области видимости.

Вот полный исходник и результаты теста.

<?php
 function array_count_value1 ($array,$val) {
  return count(array_filter($array, function($item) { global $val; return $item==$val; }));
 }
 
 function array_count_value2 ($array,$val) {
  $a = array_count_values ($array);
  foreach ($a as $key=>$value) if ($key==$val) return $value;
  return 0;
 }

 function array_count_value3 ($array,$val) {
  $count=0;
  foreach ($array as $item) if ($item==$val) $count++;
  return $count;
 }
 
 $a = array ();
 for ($i=0; $i<1e6; $i++) $a[] = rand(0,99);
 $val = 1;

 $start = microtime(true);
 $r1 = array_count_value1 ($a,$val);
 $end = microtime(true);
 echo '<br>function 1, result='.$r1.', '.round($end-$start,4).' ms';

 $start = microtime(true);
 $r2=array_count_value2 ($a,$val);
 $end = microtime(true);
 echo '<br>function 2, result='.$r2.', '.round($end-$start,4).' ms';

 $start = microtime(true);
 $r3=array_count_value3 ($a,$val);
 $end = microtime(true);
 echo '<br>function 3, result='.$r3.', '.round($end-$start,4).' ms';
?>
function 1, result=10007, 2.2433 ms
function 2, result=10007, 0.0231 ms
function 3, result=10007, 0.05775 ms

В PHP7 и на мощном компьютере результаты более обнадёживающие, но тенденция та же:

function 1, result=9972, 0.0481 ms
function 2, result=9972, 0.0035 ms
function 3, result=9972, 0.0111 ms

16.10.2015, 16:16 [7274 просмотра]


теги: php алгоритм время тест

К этой статье пока нет комментариев, Ваш будет первым