gpt4 book ai didi

php - 减少数组和 SplFixedArray 的内存使用

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:44:43 25 4
gpt4 key购买 nike

我在 array()SplFixedArray() 之间做了一些基准测试,我遇到了奇怪的行为。先看我的简单测试(其实就是网上的剪辑版,不好意思,我现在找不到原始出处了):

function formatMemoryUsage($usage) {
$unit = array(' B', 'kB', 'MB', 'GB', 'TB');
$factor = floor((strlen($usage) - 1) / 3);

return sprintf('%.2f %s (%d bytes) ', $usage / pow(1024, $factor), $unit[$factor], $usage);
}

for($size = 1000; $size < 100000; $size *= 2) {
echo PHP_EOL . '> Testing size: ' . number_format($size) . PHP_EOL;
echo ' Array()' . PHP_EOL;

for($s = microtime(true), $m = memory_get_usage(true), $container = Array(), $i = 0; $i < $size; $i++) $container[$i] = null;
echo ' - Write - time : ' . str_pad(microtime(true) - $s, 20, '0') . ' - memory: ' . formatMemoryUsage(memory_get_usage(true) - $m) . PHP_EOL;

$s = microtime(true);
foreach ($container as $key => $value) {
$void = $value;
}
echo ' - Read - time : ' . str_pad(microtime(true) - $s, 20, '0') . PHP_EOL;

unset($container);

echo ' SplFixedArray()' . PHP_EOL;

for($s = microtime(true), $m = memory_get_usage(true), $container = new SplFixedArray($size), $i = 0; $i < $size; $i++) $container[$i] = null;
echo ' - Write - time : ' . str_pad(microtime(true) - $s, 20, '0') . ' - memory: ' . formatMemoryUsage(memory_get_usage(true) - $m) . PHP_EOL;

$s = microtime(true);
foreach ($container as $key => $value) {
$void = $value;
}
echo ' - Read - time : ' . str_pad(microtime(true) - $s, 20, '0') . PHP_EOL;

unset($container);
}

结果有点符合预期 - SplFixedArray() 写入速度更快,读取速度稍慢。当我在前一个 unset() 之后放置另一个相同的 SplFixedArray() 测试时,事情开始变得奇怪,查看输出:

> Testing size: 64,000
Array()
- Write - time : 0.009041070938110400 - memory: 7.50 MB (7864320 bytes)
- Read - time : 0.004010915756225600
SplFixedArray()
- Write - time : 0.004639148712158200 - memory: 1.75 MB (1835008 bytes)
- Read - time : 0.005971908569335900
SplFixedArray()
- Write - time : 0.005653858184814500 - memory: 1.50 MB (1572864 bytes)
- Read - time : 0.006288051605224600

为什么第二个测试比第一个测试使用更少的内存?嘿,我尝试添加下一个测试并且:

> Testing size: 64,000
Array()
- Write - time : 0.008963823318481400 - memory: 7.50 MB (7864320 bytes)
- Read - time : 0.004142045974731400
SplFixedArray()
- Write - time : 0.005026102066040000 - memory: 1.75 MB (1835008 bytes)
- Read - time : 0.005756139755249000
SplFixedArray()
- Write - time : 0.004483938217163100 - memory: 1.50 MB (1572864 bytes)
- Read - time : 0.005591869354248000
SplFixedArray()
- Write - time : 0.004633903503418000 - memory: 1.25 MB (1310720 bytes)
- Read - time : 0.005697011947631800

因此,我当然会尝试添加越来越多的内容,然后再减少一些内容,然后停止在 512 kB 上。我的问题很明显:这怎么可能,为什么当我取消设置以前的对象并创建新对象时,使用的内存较低?它适用于正常的 array()也是。

最佳答案

如果我们想了解这一点,我们需要进入引擎。更好:在 Zend/zend_alloc.c (The Zend Memory Manager) 内部.

内存管理器分配的内存被分割成 block 256 KB .

释放 SPLFixedArray 后,only the first contiguous chunk of memory is freed .总会有一个 256 KB 的 block (一些变量)然后累积。 (这是因为操作系统分配的下一个内存将与该内存块相邻)

这个内存段就是marked as free并尽可能在下次使用,而不是从操作系统分配新内存。 (如果有必要,还会附加一些内存)

但由于至少有一个 256 KB 的 block 总是被释放,我们总是会注意到 256 KB 的差异。


当您想测量内存使用情况时,我真的会使用 memory_get_usage(false),因为它指示您 PHP(≠ Zend)需要多少内存。 (唯一不利于 memory_limit ini 设置的东西)

关于php - 减少数组和 SplFixedArray 的内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21453915/

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