【问题标题】:Speeding up PHP foreach loop with unset()?使用 unset() 加速 PHP foreach 循环?
【发布时间】:2013-12-31 20:01:27
【问题描述】:

根据我所读到的关于 php 数组内部的内容,这可能是不可能的,但我想通过你的方式运行它,看看是否有机会......

我从 SQL 查询中提取两个结果集。一个是客户数组(实际上是数组数组 - 每个客户都有 ID 和一些其他个人数据),第二个数组是客户订单数组(也是数组数组)。基本上,我的 foreach 循环将客户数组中的客户 ID 值与客户在第二个数组中所做的所有订单进行匹配,并将它们推送到新的第三个数据结构中。

假设我进行了 SQL 查询,并提取了一个包含 500 个客户和 3,000 个订单的数组。平均而言,一位客户将有六个订单要匹配。对于通过客户数组的每次迭代,我还需要遍历整个订单数组以获取所有匹配项。然后我会将它们推入一个不同的数据结构中,这就是我最终将使用的。

我想知道从两个原始数组中取消设置匹配的行是否会加快 foreach 循环,因为原则上每个循环的迭代次数会更少。基于 PHP 如何为其数组使用散列和存储桶,以及它在 foreach 循环中复制数组的方式,我想知道是否真的会提高性能。我计划用一些虚拟数据对此进行测试,但我想知道这里是否有人遇到过类似的情况。

谢谢!!

编辑 - 感谢您的回答。是的,加入表格可能是最好的方法,但我问这个问题是为了更好地了解 PHP 如何处理数组等。

我写了一个测试脚本,现在我可以看到使用 unset() 对我没有帮助:

$customers = Array('1' =>'Jim', '2' => 'Bill', '3' => 'John', '4' => 'Ed', '5' => 'Greg');
$orders = Array();
$final = Array();

for ($x = 0; $x < 1000000; $x++) {
    $orders[$x] = rand(1,5);
}

$start = microtime(true);
$counter = 0;
foreach ($customers as $key=>$customer) {
    $final[$customer] = Array();
    foreach ($orders as $key=>$order) {
        $counter++; 
        if ($order == $key) {
            $final[$customer][] = $order;
            unset($orders[$key]);               
        }
    }
}
echo $counter; // I usually get the same number of iterations whether unset() is used or not

$finish = microtime(true) - $start; // similar or worse performance if unset() is used

我看到 unset() 并没有提高性能,而是降低了。最重要的是, unset() 实际上并没有从数组中删除该行。当我对 $orders 数组进行 count() 操作时,它的结尾与开头相同。

【问题讨论】:

  • 不要那样做。你需要做一个连接并一举将所有数据拉回。不要查询数据库两次,然后在 php 中执行关系数据库工作(建立数据之间的关系)。
  • 为什么不简单地加入查询中的结果集呢?这将产生最佳性能……

标签: php arrays foreach unset associative


【解决方案1】:

根据我的理解,您将分别获得客户的结果和从数据库中单独订购数据。

客户

ID   名称  添加..

1   一个   ...

2                                            ...

3                                                                                                                            ...

订单

ID                                                                                                                                                                                                 

ID

1                                ...

2    3    ....

3    3    ....

4    2    ....

同时检索数据本身加入表格并获得所需的结果,例如..

从客户 c 中选择 c.Name、c.ID、o.ord LEFT JOIN 订单 o ON c.ID = o.CID;

您可以根据需要添加where条件;

【讨论】:

    【解决方案2】:

    这只是我的想法:

    使用 'arrayxyz[]' 语法将数据附加到另一个数组可能比 'unset' 更快,因为需要运行以保持 'foreach' 处于有用状态的逻辑开销。

    此外,取消设置数组项会删除键/值,如果您使用数字索引,则会留下一个“漏洞”,可能会或可能不会影响“计数”功能。

    您可能需要使用“array_values”重新索引数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 2012-07-19
      相关资源
      最近更新 更多