Проверка наличия пустых массивов: считать против пустых - PullRequest
91 голосов
/ 07 февраля 2010

Этот вопрос о Как узнать, пуст ли массив PHP , заставил меня задуматься над этим вопросом

Есть ли причина, по которой count следует использовать вместо empty при определении, массив пуст или нет?

Моя личная мысль была бы, если 2 эквивалентны для случая пустых массивов, которые вы должны использовать empty, потому что это дает логический ответ на логический вопрос. Из вопроса, связанного выше, кажется, что count($var) == 0 является популярным методом. Для меня, хотя технически правильно, не имеет смысла. Например. В: $ var, ты пустой? A: 7 . Ммм ...

Есть ли причина, по которой я должен использовать count == 0 вместо этого или просто вопрос личного вкуса?

Как отмечают другие в комментариях к удаленному ответу, count будет влиять на производительность для больших массивов, поскольку ему придется считать все элементы, тогда как empty может остановиться, как только узнает, что это не так. пустой. Итак, если они дают одинаковые результаты в этом случае, но count потенциально неэффективен, зачем нам использовать count($var) == 0?

Ответы [ 12 ]

90 голосов
/ 07 февраля 2010

Я обычно использую empty. Я не уверен, почему люди используют счет действительно - если массив большой, то счет занимает больше времени / имеет больше накладных расходов. Если вам просто нужно узнать, является ли массив пустым, используйте пустой.

41 голосов
/ 14 апреля 2015

Мне было любопытно посмотреть, какой из них на самом деле быстрее, поэтому я сделал простой скрипт для сравнения этих функций.

<?php

function benchmark($name, $iterations, $action){
    $time=microtime(true);
    for($i=0;$i<=$iterations;++$i){
        $action();
    }
    echo $name . ' ' . round(microtime(true)-$time, 6) . "\n";
}

$iterations = 1000000;
$x = array();
$y = range(0, 10000000);
$actions = array(
    "Empty empty()" => function() use($x){
        empty($x);
    },
    "Empty count()" => function() use($x){
        count($x);
    },
    "Full empty()" => function() use($y){
        empty($y);
    },
    "Full count()" => function() use($y){
        count($y);
    },
    ############
    "IF empty empty()" => function() use($x){
        if(empty($x)){ $t=1; }
    },
    "IF empty count()" => function() use($x){
        if(count($x)){ $t=1; }
    },
    "IF full empty()" => function() use($y){
        if(empty($y)){ $t=1; }
    },
    "IF full count()" => function() use($y){
        if(count($y)){ $t=1; }
    },
    ############
    "OR empty empty()" => function() use($x){
        empty($x) OR $t=1;
    },
    "OR empty count()" => function() use($x){
        count($x) OR $t=1;
    },
    "OR full empty()" => function() use($y){
        empty($y) OR $t=1;
    },
    "OR full count()" => function() use($y){
        count($y) OR $t=1;
    },
    ############
    "IF/ELSE empty empty()" => function() use($x){
        if(empty($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE empty count()" => function() use($x){
        if(count($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full empty()" => function() use($y){
        if(empty($y)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full count()" => function() use($y){
        if(count($y)){ $t=1; } else { $t=2; }
    },
    ############
    "( ? : ) empty empty()" => function() use($x){
        $t = (empty($x) ? 1 : 2);
    },
    "( ? : ) empty count()" => function() use($x){
        $t = (count($x) ? 1 : 2);
    },
    "( ? : ) full empty()" => function() use($y){
        $t = (empty($y) ? 1 : 2);
    },
    "( ? : ) full count()" => function() use($y){
        $t = (count($y) ? 1 : 2);
    }
);

foreach($actions as $name => $action){
    benchmark($name, $iterations, $action);
}
//END

Так как я делал это, я также пытался проверить производительность выполнения операций, которые обычно были бы связаны с count () / empty ()

Использование PHP 5.4.39:

Empty empty() 0.118691
Empty count() 0.218974
Full empty() 0.133747
Full count() 0.216424
IF empty empty() 0.166474
IF empty count() 0.235922
IF full empty() 0.120642
IF full count() 0.248273
OR empty empty() 0.123875
OR empty count() 0.258665
OR full empty() 0.157839
OR full count() 0.224869
IF/ELSE empty empty() 0.167004
IF/ELSE empty count() 0.263351
IF/ELSE full empty() 0.145794
IF/ELSE full count() 0.248425
( ? : ) empty empty() 0.169487
( ? : ) empty count() 0.265701
( ? : ) full empty() 0.149847
( ? : ) full count() 0.252891

Использование HipHop VM 3.6.1 (dbg)

Empty empty() 0.210652
Empty count() 0.212123
Full empty() 0.206016
Full count() 0.204722
IF empty empty() 0.227852
IF empty count() 0.219821
IF full empty() 0.220823
IF full count() 0.221397
OR empty empty() 0.218813
OR empty count() 0.220105
OR full empty() 0.229118
OR full count() 0.221787
IF/ELSE empty empty() 0.221499
IF/ELSE empty count() 0.221274
IF/ELSE full empty() 0.221879
IF/ELSE full count() 0.228737
( ? : ) empty empty() 0.224143
( ? : ) empty count() 0.222459
( ? : ) full empty() 0.221606
( ? : ) full count() 0.231288

Выводы, если вы используете PHP:

  1. empty () намного быстрее, чем count () в обоих сценариях, с пустым и заполненным массивом

  2. count () выполняет то же самое с полным или пустым массивом.

  3. Выполнение простой операции IF или просто логической операции - то же самое.

  4. IF / ELSE намного более эффективен, чем (?:). Если вы не выполняете миллиарды итераций с выражениями в середине, это совершенно незначительно.

Выводы, если вы используете HHVM:

  1. empty () немного быстрее, чем count (), но незначительно.

    [Остальное такое же, как в PHP]

В заключение, если вам просто нужно знать, является ли массив пустым, всегда используйте empty ();

Это был просто любопытный тест, просто проведенный без учета многих вещей. Это просто подтверждение концепции и может не отражать операции на производстве.

15 голосов
/ 07 февраля 2010

Я думаю, что это только личные предпочтения. Некоторые люди могут сказать, что empty быстрее (например, http://jamessocol.com/projects/count_vs_empty.php), в то время как другие могут сказать, что count лучше, поскольку он изначально был создан для массивов. empty является более общим и может применяться к другим типам.

php.net выдает следующее предупреждение для count:

count () может вернуть 0 для переменной, которая не установлена, но может также вернуть 0 для переменной, которая была инициализирована с пустым массивом Используйте isset (), чтобы проверить, установлена ​​ли переменная.

Другими словами, если переменная не установлена, вы получите уведомление от PHP о том, что она не определена. Поэтому перед использованием count было бы предпочтительно проверить переменную с помощью isset. Это не обязательно с empty.

10 голосов
/ 07 февраля 2010

Есть ли причина, по которой при определении, является ли массив пустым или нет, следует использовать счетчик вместо пустого?

Существует, когда вам нужно что-то сделать с непустым массивом, зная, что он имеет размер:

if( 0 < ( $cnt = count($array) ) )
{
 echo "Your array size is: $cnt";
}
else
 echo "Too bad, your array is empty :(";

Но я бы не рекомендовал использовать count, если вы не уверены на 100%, что то, что вы рассчитываете, является массивом. В последнее время я отлаживал код, в котором при ошибке функция возвращала FALSE вместо пустого массива, и я обнаружил:

var_dump(count(FALSE));

выход:

int 1

Так что с тех пор я использую empty или if(array() === $array), чтобы убедиться, что у меня есть массив , который пуст.

6 голосов
/ 13 июля 2015

count(), кажется, лучше работает с массивными интерфейсами, которые реализуют ArrayAccess/Countable. empty() возвращает true для таких объектов, даже если они не имеют элементов. Обычно эти классы реализуют интерфейс Countable, поэтому, если вопрос «Содержит ли эта коллекция элементы?» без предположения о реализации, тогда count() является лучшим вариантом.

5 голосов
/ 07 апреля 2011

Кроме того, вы можете привести переменную как логическое значение (неявно или явно):

if( $value )
{
  // array is not empty
}

if( (bool) $value )
{
  // array is still not empty
}

Этот метод генерирует E_NOTICE, если переменная не определена, аналогично count().

Для получения дополнительной информации см. страницу руководства PHP по сравнению типов .

3 голосов
/ 10 апреля 2015

Надеюсь, что это может кому-то помочь, даже если на него уже был дан ответ (и кое-что обсуждалось). В моем собственном сценарии я знаю, что все мои массивы имеют 7 элементов (проверки были сделаны ранее в моем коде), и я выполняю array_diff, который, конечно, возвращает нулевой массив, когда равен.

У меня было 34 секунды для count и 17 секунд для empty. Оба дают мне одинаковые вычисления, поэтому мой код все еще в порядке.

Однако вы также можете попробовать == или ===, как в PHP - Проверьте, равны ли два массива . Лучшее, что я могу сказать, это попробовать count против empty против == empty array, а затем посмотреть, какой из них даст вам лучший результат. В моем случае count был самым медленным, поэтому я использую empty, сейчас ... буду проверять serialize, следующий

3 голосов
/ 16 июня 2010

Мои личные предпочтения больше касаются элегантности кодирования (по отношению к моему конкретному варианту использования). Я согласен с Дэном МакГом, поскольку count () не отвечает с правильным типом данных (в данном случае логическим) для рассматриваемого теста, заставляя разработчика писать больше кода для заполнения оператора if.

Вопрос о том, оказывает ли это какое-либо существенное влияние на производительность, является спорным только для очень больших массивов (которые, вероятно, не будут выделяться в любом случае для большинства установок).

В частности, когда речь заходит о массиве PHP _POST, на мой взгляд, гораздо более «логично» написать / посмотреть:

if ( !empty ( $_POST ) ) {
    // deal with postdata
}
1 голос
/ 19 июня 2013

Иногда использование empty является обязательным.Например, этот код:

$myarray = array();

echo "myarray:"; var_dump($myarray); echo "<br>";
echo "case1 count: ".count($myarray)."<br>";
echo "case1 empty: ".empty($myarray)."<br>";

$glob = glob('sdfsdfdsf.txt');

echo "glob:"; var_dump($glob); echo "<br>";
echo "case2 count: ".count($glob)."<br>";
echo "case2 empty: ".empty($glob);

Если вы запустите этот код следующим образом: http://phpfiddle.org/main/code/g9x-uwi

Вы получите такой вывод:

myarray:array(0) { } 
case1 count: 0
case1 empty: 1

glob:bool(false) 
case2 count: 1
case2 empty: 1

Так что если вы count пустой вывод глобуса вы получаете неправильный вывод.Вы должны проверить пустоту.

Из glob документация:

Возвращает массив, содержащий совпавшие файлы / каталоги, пустой массив, если файл не найден или FALSEпри ошибке.
Примечание. В некоторых системах невозможно различить пустое совпадение и ошибку.

Также проверьте этот вопрос: Почему count (false) возвращает 1?

1 голос
/ 07 февраля 2010

Нет веских причин предпочитать count($myArray) == 0 над empty($myArray). У них одинаковая семантика. Некоторые могут найти один более читаемый, чем другой. Один может работать немного лучше, чем другой, но вряд ли это будет существенным фактором в подавляющем большинстве приложений php Для всех практических целей выбор - дело вкуса.

...