Checking for empty arrays: count vs empty

前端 未结 12 557
隐瞒了意图╮
隐瞒了意图╮ 2020-12-07 12:59

This question on \'How to tell if a PHP array is empty\' had me thinking of this question

Is there a reason that count should be used instead of e

相关标签:
12条回答
  • 2020-12-07 13:43

    Hope this might help someone even though it has already been answered (and debated some what). In my own scenario, I know all my arrays all have 7 elements (checks were made earlier in my code) and I am performing an array_diff which of course returns an array of zero when equal.

    I had 34 sec for count and 17 sec for empty. Both give me the same calculations so my code is still fine.

    However you can also try the == or === as in PHP - Check if two arrays are equal. The best I would say is try count vs empty vs == empty array, then see which gives your own best perfs. In my case count was the slowest so I am using empty now... will be checking serialize next

    0 讨论(0)
  • 2020-12-07 13:45

    I was curious to see which one was actually faster so I made a simple script to benchmark those functions.

    <?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
    

    Since I was doing it I also tried to check the performance doing operations that would normally be associated with count()/empty()

    Using 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
    

    Using 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
    

    Conclusions if you're using PHP:

    1. empty() is much much faster than count() in both scenarios, with an empty and populated array

    2. count() performs the same with a full or empty array.

    3. Doing a simple IF or just a Boolean operation is the same.

    4. IF/ELSE is very slightly more efficient than ( ? : ). Unless you're doing billions of iterations with expressions in the middle it is completely insignificant.

    Conclusions if you're using HHVM:

    1. empty() is a teeny-weeny bit faster than count() but insignificantly so.

      [ The rest is the same as in PHP ]

    In conclusion of the conclusion, if you just need to know if the array is empty always use empty();

    This was just a curious test simply done without taking many things into account. It is just a proof of concept and might not reflect operations in production.

    0 讨论(0)
  • 2020-12-07 13:48

    Alternatively, you can cast the variable as a boolean (implicitly or explicitly):

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

    This method does generate an E_NOTICE if the variable is not defined, similarly to count().

    For more information, see the PHP Manual page on type comparisons.

    0 讨论(0)
  • 2020-12-07 13:51

    I remade my mind guys, thanks.

    Ok, there is no difference between the usage of empty and count. Technically, count should be used for arrays, and empty could be used for arrays as well as strings. So in most cases, they are interchangeable and if you see the php docs, you will see the suggestion list of count if you are at empty and vice versa.

    0 讨论(0)
  • 2020-12-07 13:54

    I think it's only personal preference. Some people might say empty is faster (e.g. http://jamessocol.com/projects/count_vs_empty.php) while others might say count is better since it was originally made for arrays. empty is more general and can be applied to other types.

    php.net gives the following warning for count though :

    count() may return 0 for a variable that isn't set, but it may also return 0 for a variable that has been initialized with an empty array. Use isset() to test if a variable is set.

    In other words, if the variable is not set, you will get a notice from PHP saying it's undefined. Therefore, before using count, it would be preferable to check the variable with isset. This is not necessary with empty.

    0 讨论(0)
  • 2020-12-07 13:54

    Since a variable parsed as negative would return int(1) with count()

    I prefer ($array === [] || !$array) to test for an empty array.

    Yes, we should expect an empty array, but we shouldn't expect a good implementation on functions without enforced return types.

    Examples with count()

    var_dump(count(0));
    > int(1)
    var_dump(count(false));
    > int(1)
    
    0 讨论(0)
提交回复
热议问题