gpt4 book ai didi

php - 减少 PHP 中递归函数的内存使用量

转载 作者:行者123 更新时间:2023-12-02 07:20:53 25 4
gpt4 key购买 nike

我在 PHP 中有一个递归函数,它在 API 中循环,只允许您一次恢复 200 条记录。

但由于此 API 的响应延迟非常高,我们决定使用本地中间数据库,在其中添加这些记录,并且这些记录将显示在网站上。

但是,由于此 API 有超过 30000 条记录,因此递归函数会消耗大量内存,因此在 30000 条记录的情况下,它必须递归调用超过 1500 次,最终导致著名的 StackOverflow .

不知道有没有手动清除这个函数内存的方法,再次调用它而不丢失它的值。

代码示例:

public function recursive ($index = 0, $offset = 200) {
$api = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api $value) {
\\Here is my necessary loop
}
if (count ($API) > 0) {
$this Recursive ($index + 200, $offset + 200);
}
}

我想找到一种方法,当它再次调用递归函数时,会在不丢失传递的引用值的情况下消除先前的分配。

最佳答案

扩展 user3720435's answer ,每次运行函数时都会创建一个新的 $api 变量,从而使用大量内存。为了理解为什么,让我们“展开”代码——想象一下它是按顺序写出来的,没有函数调用:

$api1 = GetConectApi ($index1, offset1)-> Getrecords ();
foreach ($api1 => $value1) {
// Here is my necessary loop
}
if (count ($api1) > 0) {
// RECURSION HAPPENS HERE
$index2 = $index1 + 200, $offset2 = $offset1 + 200
$api2 = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api2 => $value2) {
// Here is my necessary loop
}
if (count ($api2) > 0) {
// RECURSE AGAIN, AND AGAIN, AND AGAIN
}
}

请注意,我已将所有变量重命名为 $api1$api2 等。这是因为每次运行该函数时,$api 实际上是一个不同的变量。它在您的源代码中具有相同的名称,但它不代表同一 block 内存。

现在,当您创建 $api2 时,PHP 不知道您不会再次使用 $api1,因此它必须将两者都保存在内存中;随着您最终获得越来越多的数据集,它需要越来越多的内存。

user3720435的建议是在递归前加上unset($api):

$api = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api => $value) {
// Here is my necessary loop
}
if (count ($api) > 0) {
unset($api);
// code as before
}

这告诉 PHP 您不再需要该内存,因此当它递归时,它不会建立。您仍将构建 $index$offset 的多个副本,但相比之下它们可能非常小。

说了这么多,还不清楚为什么你需要在这里递归。整个事情实际上可以改为一个简单的循环:

do {
$api = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api => $value1) {
// Here is my necessary loop
}
$index = $index + $offset;
} while (count ($api) > 0)

do..while 循环总是执行一次,然后不断重复,直到条件变为 false。展开它看起来像这样:

// do...
$api = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api => $value1) {
// Here is my necessary loop
}
$index = $index + $offset;
if (count ($api) > 0) { // while...
$api = GetConectApi ($index, offset)-> Getrecords ();
foreach ($api => $value1) {
// Here is my necessary loop
}
$index = $index + $offset;
}
if (count ($api) > 0) { // while...
// etc

请注意,我们在循环时不需要分配任何额外的内存,因为我们没有输入新函数 - 我们只是一遍又一遍地使用相同的变量。

关于php - 减少 PHP 中递归函数的内存使用量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46429216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com