如何修复循环中的php内存问题

如何修复循环中的php内存问题,php,Php,我有一个循环,它通过给出所需的位数来生成所有可能的位数组合,但问题是当位数超过20时,我的内存就用完了,我能做些什么优化来解决这个问题 这是我的代码: function bitsGenerator($N) { $listN = $N; $bits = ['0', '1']; //check if input is valid or not if (!is_int($listN)) { echo 'Input must be numeric!';

我有一个循环,它通过给出所需的位数来生成所有可能的位数组合,但问题是当位数超过20时,我的内存就用完了,我能做些什么优化来解决这个问题

这是我的代码:

function bitsGenerator($N)
{
    $listN = $N;
    $bits = ['0', '1'];

    //check if input is valid or not
    if (!is_int($listN)) {
        echo 'Input must be numeric!';
    }

    if ($listN >= 1 && $listN <= 65) {
        if ($listN == 1) {
            echo '1';
            exit;
        }

        for ($i = 1; $i <= ($listN - 1); $i++) {
            $reverseBits = array_reverse($bits);

            $prefixBit = preg_filter('/^/', '0', $bits);

            $prefixReverseBits = preg_filter('/^/', '1', $reverseBits);

            $bits = array_merge($prefixBit, $prefixReverseBits);

            unset($prefixBit, $prefixReverseBits, $reverseBits);
        }

        $finalBits = array_slice($bits, -$listN);

        foreach ($finalBits as $k => $v) {
            echo $v . "\n";
        }
    } else {
        echo 'Invalid input!';
    }
}
函数位生成器($N)
{
$listN=$N;
$bits=['0','1'];
//检查输入是否有效
如果(!is_int($listN)){
echo“输入必须是数字!”;
}

如果($listN>=1&&$listN,主要问题是保存所有结果的
$bits
数组的大小。该数组将包含2^$N个元素,每个元素的长度为$N乘以每个字符的8位(因为您使用字符串具有前导零),因此最终的内存消耗约为(2^$N)*$N*8,即167772160字节。使用RAM时不会变小

$bits
preg_filter
array_merge
的工作副本也将消耗大量RAM。使用
$N=20
运行函数将消耗180375552(172MiB)

顺便说一句:
unset
ing变量不会减少消耗的RAM,因为它们无论如何都会在下一次迭代中被覆盖(或在函数结束时被破坏)

下面的函数是我根据您的函数绘制的第一个草图,它使用的RAM少了一点:171970560字节或164MiB(VS172MIB)

您可以使用此生成器生成

如果您真的需要使用更少的RAM,您应该考虑将其存储在一个文件中,这会使整个过程变得更慢,但它将使用更少的RAM

function fileBitsGenerator($length)
{
    $handle = fopen('bits.txt', 'w+');

    $iterations = pow(2, $length);

    for ($i = 0; $i < $iterations; $i++) {
        fwrite($handle, str_pad(decbin($i), $length, '0', STR_PAD_LEFT) . PHP_EOL);
    }
}
函数文件位生成器($length)
{
$handle=fopen('bits.txt','w+');
$iterations=pow(2,$length);
对于($i=0;$i<$iterations;$i++){
fwrite($handle,str_pad(decbin($i),$length,'0',str_pad_LEFT).PHP_EOL);
}
}
这只需要2097152字节和刻度!
但请注意,性能将取决于您的HDD/SSD速度,它会执行大量写入操作(这可能会缩短SSD的使用寿命)。例如:如果
length=22

则结果文件bits.txt的大小为92MB。主要问题是保存所有结果的
$bits
数组的大小。该数组将包含2^$N个元素,每个元素的长度为$N乘以每个字符的8位(因为您使用的字符串具有前导零)因此,最终的内存消耗约为(2^$N)*$N*8,即167772160字节。使用RAM时,内存不会变小

$bits
preg_filter
array_merge
的工作副本也将消耗大量RAM。使用
$N=20
运行函数将消耗180375552(172MiB)

顺便说一句:
unset
ing变量不会减少消耗的RAM,因为它们无论如何都会在下一次迭代中被覆盖(或在函数结束时被破坏)

下面的函数是我根据您的函数绘制的第一个草图,它使用的RAM少了一点:171970560字节或164MiB(VS172MIB)

您可以使用此生成器生成

如果您真的需要使用更少的RAM,您应该考虑将其存储在一个文件中,这会使整个过程变得更慢,但它将使用更少的RAM

function fileBitsGenerator($length)
{
    $handle = fopen('bits.txt', 'w+');

    $iterations = pow(2, $length);

    for ($i = 0; $i < $iterations; $i++) {
        fwrite($handle, str_pad(decbin($i), $length, '0', STR_PAD_LEFT) . PHP_EOL);
    }
}
函数文件位生成器($length)
{
$handle=fopen('bits.txt','w+');
$iterations=pow(2,$length);
对于($i=0;$i<$iterations;$i++){
fwrite($handle,str_pad(decbin($i),$length,'0',str_pad_LEFT).PHP_EOL);
}
}
这只需要2097152字节和刻度!
但是请注意,性能将取决于您的HDD/SSD速度,它会执行许多写入操作(这可能会缩短SSD的寿命)。例如:如果php.ini文件中的
length=22

搜索
memory\u limit
,则结果文件bits.txt的大小为92MB,并增加该值。添加
ini\u集(“memory\u limit”,“-1”)
在页面的第一行……最好的优化方法不是在内存中构建大型数组;难道你不能在构建结果时将其回显出来,而不是使用array_merge()将其添加到数组中吗?@MarkBaker我必须将它们添加到一个数组中,以便在它完成后对结果进行操作不一定如此……完成后你将如何处理它们?你能使用生成器而不是数组吗?在内存中构建大型数组从来都不是一个好主意在php.ini文件中搜索
内存\u限制
,并增加值。添加
ini_set(“memory_limit”,“-1”);
在页面的第一行中……最佳的优化方法不是在内存中构建大型数组;难道您不能在构建过程中只回显每个结果,而不是使用array_merge()将其添加到数组中吗?@MarkBaker我必须将它们添加到数组中,以便在数组完成后对结果进行操作不一定如此……完成后你将如何处理它们?你可以使用生成器而不是数组吗?在内存中构建大型数组从来都不是一个好主意。你可以通过操作
$I
(例如,使用
$i=$iterations-$length
对其进行初始化以仅生成最后一个
$length
条目。顺便说一下,您可以通过操纵
$i
来控制偏移和限制(例如,使用
$i=$iterations-$length
对其进行初始化以仅生成最后一个
$length
条目)
function fileBitsGenerator($length)
{
    $handle = fopen('bits.txt', 'w+');

    $iterations = pow(2, $length);

    for ($i = 0; $i < $iterations; $i++) {
        fwrite($handle, str_pad(decbin($i), $length, '0', STR_PAD_LEFT) . PHP_EOL);
    }
}