Проверка на наличие пустых массивов: count vs empty


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

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

моя личная мысль была бы, если 2 эквивалентны для случая пустых массивов, которые вы должны использовать empty потому что он дает логический ответ на логический вопрос. Из вопроса, связанного выше, кажется, что count($var) == 0 - Это популярный способ. Ко мне, хотя технически правильно, нет смысла. Е. Г. Q: $var, вы пусты? A: 7. Хммм...

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

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

12 84

12 ответов:

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

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

<?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. пустая() значительно гораздо быстрее, чем count () в обоих сценариях, с пустым и заполненным массивом

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

  3. выполнение простой, Если или просто логической операции то же самое.

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

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

  1. empty ()-это крошечный бит быстрее, чем count (), но незначительно.

    [ остальное то же самое, что и в PHP ]

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

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

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

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

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

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

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

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

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) чтобы быть уверенным, что у меня есть массив это пустое.

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

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

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

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

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

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

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

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

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

if ( !empty ( $_POST ) ) {
    // deal with postdata
}

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

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

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

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

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

$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 пустой вывод глобуса вы получаете неправильный вывод. Вы должны проверить на пустоту.

С Глоб документы:

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

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

я переделал свой ум, ребята, спасибо.

ок, нет никакой разницы между использованием empty и count. Технически,count должны использоваться для массивов, и empty может использоваться как для массивов, так и для строк. Поэтому в большинстве случаев они взаимозаменяемы, и если вы видите документы php, вы увидите список предложений count Если вы находитесь в empty и наоборот.

С переменной интерпретируется как отрицательный вернется int(1) С count()

предпочитаю ($array === [] || !$array) для проверки пустого массива.

Да, мы должны ожидать пустой массив, но мы не должны ожидать хорошей реализации функций без принудительных возвращаемых типов.

примеры count()

var_dump(count(0));
> int(1)
var_dump(count(false));
> int(1)