count()Действительно ли подсчитываются все элементы массива PHP, или это значение где-то кэшируется и просто извлекается?
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.
IS_CONSISTENT(ht)делать?
В PHP 5+ длина хранится в массиве, поэтому подсчет не выполняется каждый раз.
РЕДАКТИРОВАТЬ: Вам также может показаться интересным этот анализ: Производительность подсчета PHP . Хотя длина массива поддерживается массивом, все же кажется, что быстрее удержать его, если вы собираетесь вызывать count()много раз.
PHP хранит размер массива внутри, но вы все равно вызываете функцию, когда это медленнее, чем ее не делать, поэтому вы захотите сохранить результат в переменной, если вы делаете что-то вроде использования ее в цикл:
Например,
$cnt = count($array);
for ($i =0; $i < $cnt; $i++) {
foo($array[$i]);
}
Кроме того, вы не всегда можете быть уверены, что countвызывается массив. Если он вызывается для объекта, который, Countableнапример, реализует , countбудет вызван метод этого объекта.
the count method of that object will be called, не могли бы вы объяснить это немного
Countableинтерфейс, то вызов count($object)- это то же самое, что и вызов $object->count(). См., Например, 3v4l.org/oYSSC .
you're still making a function call when which is slower than not making oneЭто утверждение может быть неверным. Если вы выполняете обход вручную, это O(n)операция. Но если вы просто хотите получить предварительно рассчитанное значение, тогда операция O(1).