这是一种比较算法的公平方法吗?

时间:2010-10-28 10:18:09

标签: php

我想将数组转换为小写,并且想知道最有效的方法。我想出了两个选项,一个使用array_walk,另一个使用foreach,想要比较它们。这是比较两者的最佳方式吗?是否有一种我忽略的更有效的方法?

<?
$a = array_fill(0, 200000, genRandomString());
$b = array_fill(0, 200000, genRandomString());
$t = microtime(true);
array_walk($a, create_function('&$a', '$a = strtolower($a);'));
echo "array_walk: ".(microtime(true) - $t);
echo "<br />";
$t = microtime(true);
foreach($b as &$source) { $source = strtolower($source); }
echo "foreach: ".(microtime(true) - $t);


function genRandomString($length = 10) {
    $characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    $string = '';    

    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters)-1)];
    }

    return $string;
}

输出:

array_walk: 0.52975487709045
foreach: 0.29656505584717

3 个答案:

答案 0 :(得分:2)

两个问题合二为一!

如何运行测试:

就个人而言,我会为每个方法编写单独的测试脚本,然后使用Apache ab实用程序来运行测试:

ab -n 100 -c 1 http://localhost/arrayWalkTest.php
ab -n 100 -c 1 http://localhost/foreachTest.php

这给了我一组更详细的比较统计数据

我还会尝试确保这两种方法在每个测试中使用相同的数据集,而不是不同的随机数据。

最有效的方法:

你应该在你的循环之后取消设置($ source)作为一个安全措施:因为你在循环中通过引用访问,$ source仍然会包含对数组中最后一个条目的引用,并且可能会给你不可预测的结果你在脚本中的任何其他位置引用$ source。

答案 1 :(得分:1)

过去使用microtime方法而不是使用专用的探查器时,我有很多奇怪的结果,就像它存在于XDebug或Zend_Debugger中一样。此外,为了公平比较,您的数组应该是相同的,而不是两个随机数组。

此外,您可以考虑使用array_mapstrtolower

$a = array_map('strtolower', $a);

可以为array_walk保存lambda。使用create_function创建的匿名函数(与PHP 5.3's anonymous functions不同)已知速度较慢且strtolower是本机函数,因此直接使用它应该更快。

我做了一个快速的基准测试,我没有看到此方法与您的foreach之间的任何相关速度差异。像往常一样,我会说它是μ-opt。当然,如果您认为重要,您应该在现实世界的应用程序中测试它。综合基准​​很有趣,但最终没用。

在旁注中,要更改数组键,可以使用

答案 2 :(得分:0)

我不懂PHP,所以这是一个疯狂的猜测:

str_split(strtolower(implode("", $a)))