哪个更好,array_search还是in_array?

45

我有一个大的while循环函数,每次它被加载进行检查时都会使用当前的URL名称。因此,我需要知道在while循环中检查大型数组中的URL名称哪个更好,是in_array()还是array_search()函数。

7个回答

67
如果数组很大并且在循环中使用,那么两者都不是“最佳”的选择。相反,可以对数组使用 array_flip(),将 URL 变成键,并使用 isset() 来检查其是否存在。

谢谢Mario,这是另一种方法。但是与in_array和array_search函数相比,这个函数会给出更快的结果吗? - Thilak
4
PHP检查键的存在比值要快得多。如果您有一组需要经常引用的唯一值集,请始终将它们设置为键。 - Buttle Butkus
12
为了使这个方法有效,原始的数值必须是整数或字符串。虽然它对 OP 的问题适用,但不能作为一般性的解决方案。 - Frederik Krautwald

59

这里没有真正的答案。所以我自己试了一下。

$haystack = array
(
    'apple',
    'banana',
    'cherry',
    'lemon',
    'lime',
    'orange',
    'potato',
    'rutabaga'
);
$haySize = count($haystack);

$loops = isset( $_SERVER['argv'][1] ) ? $_SERVER['argv'][1] : 10000;
// echo 'Loops: ' . $loops . "\n";

$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
    $needle = $haystack[ $i % $haySize ];
}
$zeroTime = microtime(true) - $start;
// echo sprintf('%0.3f', $zeroTime * 1000) . ' ms : zero time' . "\n";

$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
    $needle = $haystack[ $i % $haySize ];
    $dummy = array_search($needle, $haystack);
}
echo sprintf('%0.3f', (microtime(true) - $start - $zeroTime) * 1000) . ' ms : array_search' . "\n";

$start = microtime(true);
for ($i = 0; $i < $loops; $i++)
{
    $needle = $haystack[ $i % $haySize ];
    $dummy = in_array($needle, $haystack);
}
echo sprintf('%0.3f', (microtime(true) - $start - $zeroTime) * 1000) . ' ms : in_array' . "\n";
    echo sprintf('%0.3f', (microtime(true) - $start) * 1000).' ms : in_array'."\n";

对于典型用例而言,使用in_array会更好,但两者的差异可以忽略不计:

22.662 ms : array_search
22.104 ms : in_array

更新于2014-01-02:在“归零刻度”中添加了一个空操作循环。 在新的MacBook Pro上运行PHP 5.4.17,这是一个典型的结果:

24.462 ms : array_search
24.984 ms : in_array

19
给出基准测试结果加一分。我想补充一下,@mario提供的array_flip/isset方法比array_search和in_array方法快得多,前提是在循环外翻转数组。在您的测试代码底部添加: $flipped = array_flip($haystack); $start = microtime(true); for ($i=0; $i<$loops; $i++) { $needle = $haystack[$i % $haySize]; $dummy = isset($flipped[$needle]); } echo sprintf('%0.3f', (microtime(true) - $start) * 1000).' ms : isset'."\n";25.281毫秒:array_search 22.345毫秒:in_array 4.895毫秒:isset - WildlyInaccurate
@PatrickFisher 在你的测试中,你计算了循环时间、$needle的初始化以及所需函数的时间。这些结果绝对不能显示in_arrayarray_search之间的差异。 - Alexander Yancharuk
它确实显示哪个更快。循环时间计算不会产生影响。您是正确的,由于循环内的$needle赋值,差异比例将减少。我假设这个赋值足够快,对结果没有太大影响。您测试过这个假设吗? - Patrick Fisher
@PatrickFisher 是的,我测试过了。但是有时候我得到了不同的结果,大约+-10%。看起来这些函数是平等的。测试源代码在这里 - Alexander Yancharuk
我怀疑问题在于每次都启动和停止计时器,而计时器只准确到微秒。这就是大量重复的全部意义——将时间增加到可测量的程度。你还只测试了最坏情况,这可能会产生与实际情况不符的结果。我的均匀分布旨在近似预期情况。 - Patrick Fisher
显示剩余4条评论

43

根据 in_arrayarray_search 的文档,我认为这主要取决于您使用信息的目的:如果需要该条目,请使用 array_search ,如果只想检查URL是否存在于数组中,则 in_array 应该足够。


2
根据时间来看,哪个是最好的? - Thilak
经过长时间的参考和根据我的需求,我选择了in_array函数。 - Thilak

7

它们是不同的函数: in_array - 如果找到值则返回 true array_search - 如果找到值则返回位置

$a = array('a', 'b');
var_dump(in_array('a', $a)); // return true
var_dump(array_search('a', $a)); // return 0 
if (array_search('a', $a)) - false

1
谢谢AmdY,是的你说得对。但我需要知道哪个函数可以获得速度结果。 - Thilak

0
如果你的目标只是检查一个URL是否存在于数组中,我会选择使用in_array。虽然最好的方法是设置键,这样你可以通过数组键进行搜索。这样可以节省很多循环的时间。
$searchword = "test";
echo $array[$searchword];

我认为你支持array_key_exists()函数,确切地说,我需要哪个函数来减少我们搜索的时间。 - Thilak

0

这取决于你的数组大小。 -如果你有一个小数组(比如<500k 32位键),in_array和array_search会给你相同的性能, isset(array[needle])没有意义,因为flip()的存在。

-对于大数组(比如>1m 32位键),in_array和isset(array[needle])之间有很大的差异。


-1
array1=array("a"=>"one","b"=>"two"); 

if(in_array("one",$array))
{
  echo "array exit"; 
 }
 else
  {
     echo " array not exist"; 
  }

echo "</br>";
//example of array_search():
 $b1=array("a"=>"one","b"=>"two");
    echo array_search("one",$b1); 

in_array 返回 true 和 false 值,而 array_search 返回数组的键


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接