【问题标题】:Speed up array comparison加快数组比较
【发布时间】:2012-12-22 17:49:26
【问题描述】:

我有两个多维数组,都包含电子邮件地址数据,但键不同,我正在尝试比较它们。我需要获取两个数组中都不存在的所有电子邮件地址,并将它们存储起来。有什么办法可以加快速度吗?

$accts: id、Email、column1 - 13000 行

$db_accts: id1, name, accountID,Email_Address__c - 17000 行

我现在有

foreach($accts as $acct){
    $exists = false;
    foreach($db_accts as $db_acct){
        if($acct['Email'] == $db_acct['Email_Address__c'])
        {   $exists = true;}
    }

    if(!$exists)
    {   $update[] = array('Email'=>$acct['Email'],'column1'=>'');
    }

}

foreach($db_accts as $db_acct){
    $exists = false;
    foreach($accts as $acct){
        if($acct['Email'] == $db_acct['Email_Address__c'])
            $exists = true; 
    }
    if(!$exists)
    {
        $update[] = array('Email'=>$db_acct['Email_Address__c'],'column1'=>'Y');
    }
}

【问题讨论】:

  • 是的。一个来自本地数据库,一个来自远程服务器。除非我加载一个临时表,否则 SQL 查询对我没有帮助。
  • 好吧,如果最终目的地是一个数据库,它仍然可能最好用 (my)sql 处理
  • 它实际上进入了第三个分贝。我正在将 company1 中的数据与我的数据进行比较,然后将其上传到 company2。两家公司的数据都通过 SOAP/REST 访问。
  • 你可以在数据库中插入一个,然后另一个,使用电子邮件地址作为唯一键,数据库将处理重复项。
  • 这只会加载数据库中的所有电子邮件地址。它不会告诉我两个地址都不存在。

标签: php


【解决方案1】:

手工

从算法上讲,你正在做的是O(|accts| * |db_accts|)

您可以通过电子邮件对两个帐户进行排序,这需要O(|accts| * log(|accts|)) + O(|db_accts| * log(|db_accts|))。然后,你可以

  1. 从两者的第一个元素开始,
  2. 比较
  3. 如果accts的元素更大,存储它并迭代到accts中的下一个元素
  4. 同样如果db_accts的元素更大
  5. 如果两者相同,则在不存储的情况下对其进行迭代。
  6. 转到 3. 如果还有元素

比较应该采用O(|accts| + |db_accts|)。如果您通过电子邮件从 DB 对它们进行排序,则将省略上面的排序步骤。否则为O(n log(n)),比O(n^2)小很多。

这应该会使您的数据集加速大约 1000 (log(17000) vs 13000)。

对于 PHP 中的排序,请查看Sort Multi-dimensional Array by Value

对于 SQL,请参阅MySQL "Group By" and "Order By"

通过 PHP

您可以使用array_diff() with multidimensional arrays

【讨论】:

    【解决方案2】:

    您应该使用array_udiff,因为它允许您自定义比较:

    array_udiff($accts,$db_accts,function($act,$dbact){
         return strcasecmp($act['Email'], $db_act['Email_Address__c']);
     });
    

    【讨论】:

      【解决方案3】:

      使用您自己的 PHP 代码比使用标准 PHP 函数要慢得多。 PHP 的标准函数在较低级别上运行,因此开销较小。使用array_diff 之类的函数会更有效率。

      【讨论】:

      • 虽然这不适用于我拥有的数组(我没有看到任何关于多维数组、比较不同键等的信息),但我想我可以只使用电子邮件地址并进行比较。
      【解决方案4】:

      使用array_diff()

      看文档,例子真的很清楚。你输入两个数组,array_diff() 吐出不同的数组。在您的情况下,电子邮件不包含在两个数组中。

      【讨论】:

      • 我没有看到任何关于具有不同键的多维数组。
      【解决方案5】:

      您可能可以使用 array_diff 来加快速度:http://de3.php.net/array_diff

      【讨论】:

      • 我没有看到任何关于具有不同键的多维数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      相关资源
      最近更新 更多