array_key_exists 和 array_search 哪个更快?

12

可能是重复问题:
PHP中判断数组键是否存在的更快更好的方法是什么?

假设我想在Memcache上存储我的朋友列表。 有时需要搜索用户是否在我的列表中,有时需要获取所有朋友列表。

你会选择

$friends[] = $friend
或者
$friends[$friend] = 1;

理念是要尽可能节省内存,同时不会影响速度。

我没有找到任何关于 PHP 5.3.8 的案例研究能够帮助我解决我的问题:

在负载下,使用 array_key_exists 还是 in_array 更快?(例如:foo 是 bar 的朋友吗?)

另外,有时我需要获取整个朋友列表,因此需要遍历整个列表以构建朋友数组。对于第二种方法一点都不确定,因为我还不知道是否会有更多的 array_search、array_key_exists、in_array 或完整的朋友列表提取。

有什么想法吗?


2
你尝试过自己制作基准测试脚本并进行测试吗?此外,这与 SO 上几乎所有其他 PHP 数组速度问题的副本相同... - James Butler
1
还没有,我当然可以对此进行一些基准测试。我很想知道是否有人能够论证这里的最佳实践应该是什么。我会发布基准测试结果。 - sathia
1
良好的实践很大程度上取决于你所处的情况。我曾经因为遵循别人的(有效)方法而受到过伤害,只是因为我的环境因素不同。当你自己动手做事时,你会发现令人惊讶的事情。 - James Butler
@DaveRandom 不是重复,因为 array_search()array_key_exists() 做的事情不同 :) - Ja͢ck
@Jack array_search 从一开始就没有存在的必要。 - Eugene
@Eugene 这是你的观点。OP 问的是针对数字数组,是使用 array_search() 还是 in_array() - Ja͢ck
2个回答

32

array_key_exists更快。 array_search必须遍历整个数组,因此它的时间复杂度为O(n)。而array_key_exists是一个哈希表查找,因此它的时间复杂度为O(1)。

如果您对这个概念还不熟悉,请参见http://en.wikipedia.org/wiki/Big_O_notation

虽然两者都非常快[O(1)],但在array_key_existsisset之间,isset显着更快。如果需要频繁进行这个检查数千次以上,您应该使用isset

值得注意的是,尽管它们不相同--当数组键存在但值为null时,isset将返回false而array_key_exists会返回true。如果值可能为null,则需要使用array_key_exists


你有具体的资源证明isset函数速度更快吗? - Francesco Pasa
我在一个大型代码库中进行了这个更改,并在当时测量出了改进。我建议你自己运行一个快速测试。在这里查看我的样本基准脚本:https://dev59.com/32855IYBdhLWcg3wIAka#7683243 - Patrick Fisher
好的,很好的基准测试,谢谢!然而我发现更快的“替代方法”是isset(),速度比其他方法快20-50%。请参见http://juliusbeckmann.de/blog/php-benchmark-isset-or-array_key_exists.html,http://www.php.net/manual/en/function.array-key-exists.php#82867或http://www.zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/。但需要注意的是,如果键存在但值为NULL,则isset()返回false。 - Francesco Pasa
我找到了另一个基准测试,证实:http://codepad.org/RcdAewVF - Francesco Pasa

2
您可以自己运行一个简单的测试。 无论如何,如果$friends应该包含唯一元素(没有重复值!),您可以使用键来存储它们。
我认为PHP检查键(array_key_exists()或简单地isset($array[$key]))会更快。 要搜索值,PHP必须循环遍历数组; 要搜索键,PHP将使用哈希函数。
您可以在stackoverflow上阅读更多信息。

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