PHP in_array() 的性能很糟糕。搜索数组值的最快方法
我有以下简单的代码来测试我正在创建的主键上的冲突:
$machine_ids = array();
for($i = 0; $i < 100000; $i++) {
//Generate machine id returns a 15 character alphanumeric string
$mid = Functions::generate_machine_id();
if(in_array($mid, $machine_ids)) {
die("Collision!");
} else {
$machine_ids[] = $mid;
}
}
die("Success!");
知道为什么这需要很多分钟才能运行吗?无论如何要加快速度吗?
I have the following simple code to test against collision on a primary key I am creating:
$machine_ids = array();
for($i = 0; $i < 100000; $i++) {
//Generate machine id returns a 15 character alphanumeric string
$mid = Functions::generate_machine_id();
if(in_array($mid, $machine_ids)) {
die("Collision!");
} else {
$machine_ids[] = $mid;
}
}
die("Success!");
Any idea why this is taking many minutes to run? Anyway to speed it up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为此,使用
$mid
作为键,使用虚拟值作为值。具体来说,您可以使用 array_keys($machine_ids) 来提取您最初想要的数组,而不是使用
最后。
这应该快得多。如果仍然很慢,那么您的
Functions::generate_machine_id()
很慢。已编辑根据评论添加
isset
。For this, use
$mid
as keys, and dummy value as value. Specifically, instead ofuse
At the end you can extract the array you originally wanted with
array_keys($machine_ids)
.This should be much faster. If it is still slow, then your
Functions::generate_machine_id()
is slow.EDITED to add
isset
as per comments.检查数组成员资格是一个 O(n) 操作,因为您必须将该值与数组中的每个元素进行比较。当你向数组添加一大堆东西后,它自然会变慢。
如果您需要进行一大堆成员资格测试,就像这里的情况一样,您应该使用支持 O(1) 成员资格测试的不同数据结构,例如哈希。
Checking for array membership is a O(n) operation, since you have to compare the value to every element in the array. After you add a whole bunch of stuff to the array, naturally it gets slower.
If you need to do a whole bunch of membership tests, as is the case here, you should use a different data structure that supports O(1) membership tests, such as a hash.
重构您的代码,以便它使用关联的数组来保存机器 ID 并使用
isset
进行检查使用
isset
应该更快Refactor your code so that it uses a associated array to hold the machine IDs and use
isset
to checkUsing
isset
should be faster如果您需要为您的情况提供最佳性能,则需要将数据存储为数组键并
使用
isset
或array_key_exists
(因为 php >= 7.4array_key_exists
现在与isset
< /em>) 而不是in_array
。以及来自 https://gist.github.com/alcaeus/536156663fac96744eba77b3e133e50a 的一些性能测试
输出:
If you need best performance for your case, you need store your data as array key and
use
isset
orarray_key_exists
(since php >= 7.4array_key_exists
is now as fast asisset
) insteadin_array
.And some performance tests from https://gist.github.com/alcaeus/536156663fac96744eba77b3e133e50a
Output: