Действительно ли count()
действительно подсчитывает все элементы массива PHP, или это значение кэшируется где-то и только извлекается?
Ну, мы можем посмотреть на источник:
/ext/standard/array.c
PHP_FUNCTION(count)
вызывает php_count_recursive()
, который в свою очередь вызывает zend_hash_num_elements()
для нерекурсивного массива, который реализован следующим образом:
ZEND_API int zend_hash_num_elements(const HashTable *ht) { IS_CONSISTENT(ht); return ht->nNumOfElements; }
Таким образом, вы можете видеть, что это O(1)
для $mode = COUNT_NORMAL
.
В PHP 5+ длина сохраняется в массиве, поэтому подсчет не выполняется каждый раз.
EDIT: Вы также можете найти этот анализ интересным: PHP Count Performance . Несмотря на то, что длина массива поддерживается массивом, все равно кажется, что быстрее удерживать его, если вы много раз вызываете count()
.
PHP хранит размер массива внутренне, но вы все равно выполняете вызов функции, когда он медленнее, чем не делает его, поэтому вы хотите сохранить результат в переменной, если вы делаете что-то вроде его использования в цикл:
Например,
$cnt = count($array); for ($i =0; $i < $cnt; $i++) { foo($array[$i]); }
Кроме того, вы не всегда можете быть уверены, что count
вызывается в массиве. Если он вызван на объект, который реализует Countable
например, будет вызван метод count
этого объекта.