PHP:在不分配太多内存的情况下将短字符串插入长字符串?



请考虑以下代码:

$position = ...
$data = substr($data, 0, $position) . $insertion . substr($data, $position);

通常$data在正在讨论的脚本的情况下不大于 2-3 MB。但是碰巧一个想要使用该脚本的用户尝试将其用于大小约为 17 MB 的$data并得到

PHP 致命错误:允许 33554432 字节的内存大小耗尽(尝试分配 17687776 字节(在//index.php 第 179 行'

其中第 179 行是上面显示的第二个 ($data = ...(,33554432 字节 = 32 MB 和 17687776> 16 MB。现在我假设问题是内存是为$datasubstr($data, 0, $position)分配的,并且substr($data, $position)。我知道内存限制,并建议他们尝试增加它。但是,我想知道我是否可以对其进行优化,以便我们不需要内存限制比$data大两倍以上。

所以我的问题是:有没有一些聪明的方法来插入$insertion以最大限度地减少内存使用量?(不要在内存中存储两次$data(substr($data, $position)相对较小的情况如何?

您当前的实现取决于目标位置。如果位置接近数据末尾,则内存效率最高。最坏的情况是插入到数据的开头。

迷你基准测试,例如:

$data      = str_repeat('abcde', 500000);
$insertion = 'abc';
$position  = 0;
$data = substr($data, 0, $position) . $insertion . substr($data, $position);
echo memory_get_peak_usage(), "n";

上面的脚本显示峰值使用量为 7868728 字节(在我的机器上(。如果我设置$position = strlen($data) / 2,那么它会打印6619424。如果在数据末尾附加字符串($position = strlen($data)(,则打印5365720。

(更新:以上代码的内存消耗也取决于PHP版本(

但是PHP已经具有替换字符串部分中的文本的有效功能:substr_replace()

$data = substr_replace($data, $insertion, $position, 0);

在所有情况下,这都需要与上述实现(通过substr()结果的串联(一样多的内存。

最新更新