请考虑以下代码:
$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。现在我假设问题是内存是为$data
和substr($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()
结果的串联(一样多的内存。