处理大型数组的array_diff函数

10

我一直在尝试比较两个数组。使用array_intersect没有问题。当我使用array_diff和包含约5000个值的数组时,它有效。但是,当我使用包含约10000个值的数组时,当我到达array_diff时,脚本会崩溃。打开error_reporting也没有产生任何效果。

我尝试创建自己的array_diff函数:

function manual_array_diff($arraya, $arrayb) {
    foreach ($arraya as $keya => $valuea) {
        if (in_array($valuea, $arrayb)) {
            unset($arraya[$keya]);
        }
    }
    return $arraya;
}

来源:How does array_diff work?

我本来以为它比官方的array_diff效率要低,但它能处理大约10,000个元素的数组。不幸的是,当数组达到 ~15,000 时,两种array_diff都无法正常运行。

我在另一台机器上尝试了相同的代码,它可以良好地运行,所以这不是代码或PHP的问题。那台特定服务器上必须设置了某些限制。有什么办法可以绕过这个限制、修改它或者只是找出它是什么?


你用什么数据进行测试的? - Gumbo
可能是因为这个算法的时间复杂度是O(N^2)。 - kennytm
你是在浏览器还是命令行中运行这个程序? - tipu
数据是一堆ID。在浏览器中运行它。 - burger
3个回答

6
遇到了同样的问题,我真的很希望在这里能得到答案。因此,我不得不自己想办法解决,并想出了以下丑陋的补救措施,对于大约50,000个元素的数组,它可以正常工作。它基于您的观察,即array_intersect有效,但array_diff无效。迟早也会超过资源限制,到那时就需要将数组分块并处理较小的部分。我们将在到达时跨越这座桥。
function new_array_diff($arraya, $arrayb) {
    $intersection = array_intersect($arraya, $arrayb);
    foreach ($arraya as $keya => $valuea) {
        if (!isset($intersection[$keya])) {
            $diff[$keya] = $valuea;
        }
    }

    return $diff;
}

1

在我的php.ini文件中:

max_execution_time = 60     ; Maximum execution time of each script, in seconds
memory_limit = 32M          ; Maximum amount of memory a script may consume

这些设置的差异或机器性能的不同是否会导致问题?如果您通过一个网站运行此程序,您是否检查了您的 Web 服务器错误日志?

它只需要几秒钟就能执行,因此执行时间不是问题。在一台机器上手动降低memory_limit确实会终止脚本。然而,在另一台机器上将memory_limit设置得更高并不能解决问题。如果你好奇的话,初始值是40M,这是在引起问题的那台机器上的。 - burger

1

您提到这是在浏览器中运行的。尝试通过命令行运行脚本,看看结果是否不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接