PHP in_array()表现糟糕。搜索数组的最快方法

时间:2011-05-23 07:01:10

标签: php arrays

我有以下简单的代码来测试我正在创建的主键上的冲突:

$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!");

知道为什么这需要花很多分钟才能运行?无论如何要加快速度?

4 个答案:

答案 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应该更快