我有以下简单的代码来测试我正在创建的主键上的冲突:
$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!");
知道为什么这需要花很多分钟才能运行?无论如何要加快速度?
答案 0 :(得分:13)
for($i = 0; $i < 100000; $i++)
{
//Generate machine id returns a 15 character alphanumeric string
$mid = Functions::generate_machine_id();
if (isset($machine_ids[$mid]))
{
die("Collision!");
}
$machine_ids[$mid] = true;
}
答案 1 :(得分:12)
为此,使用$mid
作为键,使用虚拟值作为值。具体而言,而不是
if(in_array($mid, $machine_ids)) {
die("Collision!");
} else {
$machine_ids[] = $mid;
}
使用
if(isset($machine_ids[$mid])) {
die("Collision!");
} else {
$machine_ids[$mid] = 1;
}
最后,您可以使用array_keys($machine_ids)
提取最初想要的数组。
这应该快得多。如果它仍然很慢,那么Functions::generate_machine_id()
很慢。
已编辑,根据评论添加isset
。
答案 2 :(得分:3)
检查数组成员资格是一种O(n)操作,因为您必须将该值与数组中的每个元素进行比较。在向数组添加一大堆东西之后,它自然会变慢。
如果你需要进行一大堆成员资格测试,就像这里的情况一样,你应该使用支持O(1)成员资格测试的不同数据结构,例如哈希。
答案 3 :(得分:2)
重构您的代码,使其使用关联的数组来保存计算机ID并使用isset
进行检查
if( isset($machine_id[$mid]) ) die("Collision");
$machine_ids[$mid] = $mid;
使用isset
应该更快