检查所有数组元素是否属于同一类型的PHP性能

时间:2013-11-21 10:50:14

标签: php arrays performance micro-optimization

我偶然发现了在PHP中检查数组中所有元素是否属于同一类型的最快方法。在浏览StackOverflow以执行此操作后,我决定检查哪些方法更快。我测试了不同的方法(参见下面的自我回答)。

希望这有帮助。

修改

在阅读了“微优化”之后,似乎这是一个微优化问题。我之前没有听说过这个词,令我惊讶的是,只要保持良好的代码可读性,我总是以“微优化”方式编写代码。也许我在嵌入式世界中的数据处理编程的根源已经转向了某种代码微优化器:D

2 个答案:

答案 0 :(得分:2)

$v = range(1, 100000);
$v[]=false; //Put a non-integer element at the end
$testf = 'is_int';
$result = array_reduce (
    $v, 
    function($return, $value) use ($testf) {
        return $return && $testf($value);
    },
    true
);

var_dump($result);

修改

我的笔记本电脑上的结果:

PHP 5.4.7

TEST isArrayOf_1: result = fail, t = 0.033294200897217
TEST isArrayOf_2: result = fail, t = 0.10196995735168
TEST isArrayOf_3: result = fail, t = 0.052531957626343
TEST isArrayOf_4: result = fail, t = 0.079360961914062

TEST isArrayOf_1: result = fail, t = 0.0085389614105225
TEST isArrayOf_2: result = fail, t = 0.0083901882171631
TEST isArrayOf_3: result = fail, t = 0.044848918914795
TEST isArrayOf_4: result = fail, t = 0.035619020462036

PHP 5.4.21

TEST isArrayOf_1: result = fail, t = 0.032476902008057
TEST isArrayOf_2: result = fail, t = 0.098520040512085
TEST isArrayOf_3: result = fail, t = 0.052137136459351
TEST isArrayOf_4: result = fail, t = 0.074975967407227

TEST isArrayOf_1: result = fail, t = 0.0085029602050781
TEST isArrayOf_2: result = fail, t = 0.0084490776062012
TEST isArrayOf_3: result = fail, t = 0.044224977493286
TEST isArrayOf_4: result = fail, t = 0.035413026809692

PHP 5.3.27

TEST isArrayOf_1: result = fail, t = 0.036087036132812
TEST isArrayOf_2: result = fail, t = 0.11226201057434
TEST isArrayOf_3: result = fail, t = 0.053704977035522
TEST isArrayOf_4: result = fail, t = 0.078150987625122

TEST isArrayOf_1: result = fail, t = 0.0088350772857666
TEST isArrayOf_2: result = fail, t = 0.008991003036499
TEST isArrayOf_3: result = fail, t = 0.045068979263306
TEST isArrayOf_4: result = fail, t = 0.039391994476318

PHP 5.5.5

TEST isArrayOf_1: result = fail, t = 0.029086112976074
TEST isArrayOf_2: result = fail, t = 0.057933807373047
TEST isArrayOf_3: result = fail, t = 0.03432297706604
TEST isArrayOf_4: result = fail, t = 0.052994012832642

TEST isArrayOf_1: result = fail, t = 0.0085070133209229
TEST isArrayOf_2: result = fail, t = 0.0085380077362061
TEST isArrayOf_3: result = fail, t = 0.024166107177734
TEST isArrayOf_4: result = fail, t = 0.034998178482056

答案 1 :(得分:1)

PHP代码:

//Approach 1: pass array and the name of a PHP type
function isArrayOf_1($v, $phptype) {
    if (is_array($v)) {
        foreach ($v as $elem) if (gettype($elem) != $phptype) return FALSE;
        return TRUE;
    }
    return FALSE;
}

//Approach 2: pass array and the name of a PHP type-check function (e.g.: is_int())
function isArrayOf_2($v, $testf) {
    if (is_array($v)) {
        foreach ($v as $elem) if (!call_user_func($testf, $elem)) return FALSE;
        return TRUE;
    }
    return FALSE;
}

//Approach 3: pass array and the name of a PHP type-check function (e.g.: is_int())
function isArrayOf_3($v, $testf) {    
    if (is_array($v)) {
        if (count($v) != count(array_filter($v, $testf))) return FALSE;
        return TRUE;
    }
    return FALSE;
}


//Approach 4: pass array and the name of a PHP type-check function (e.g.: is_int())
function isArrayOf_4($v, $testf) {    
    if (is_array($v)) {            
        return array_reduce (
            $v, 
            function($return, $value) use ($testf) {
                return $return && $testf($value);
            },
            true
        );
    }
    return FALSE;
}

//Number of tested functions
$TEST_FUNCTIONS = 4;

//Test data
$v = range(1, 100000);
$v[]=false; //Put a non-integer element at the end

//Tests
$tests = array(
    array('integer', 'is_int', 'is_int'), //Successful check test
    array('boolean', 'is_bool', 'is_bool') //Wrong check test
);

foreach ($tests as $test) {    
    for ($i = 1; $i <= $TEST_FUNCTIONS; $i++) {
        $start = microtime(true);
        $res =  call_user_func("isArrayOf_$i", $v, $test[$i-1]);
        $t = microtime(true) - $start;
        echo "TEST isArrayOf_$i: result = ".($res?'success':'fail').", t = $t<br/>";
    }
    echo "<br/>";
}

<强>输出

TEST isArrayOf_1: result = fail, t = 0.13473296165466
TEST isArrayOf_2: result = fail, t = 0.22269797325134
TEST isArrayOf_3: result = fail, t = 0.074767112731934
TEST isArrayOf_4: result = fail, t = 0.91770792007446

TEST isArrayOf_1: result = fail, t = 0.017352104187012
TEST isArrayOf_2: result = fail, t = 0.015971899032593
TEST isArrayOf_3: result = fail, t = 0.058960914611816
TEST isArrayOf_4: result = fail, t = 0.75518012046814

我们可以看到,如果在数组的后期找到错误的值,则方法3表现最佳。但是,如果在数组的早期出现错误的值,则方法1和2是获胜者。我们还看到方法3在两种情况下都表现相似,而其他两种方法具有不同的执行时间。最糟糕的方法似乎是#4 ...任何想法为什么?

所以,恕我直言,方法3是我选择检查数组中所有元素是否属于给定类型的方法。