如果你想要一个真正的索引数组,请使用 SplFixedArray。它使用较少的内存。此外,PHP 5.3 有一个更好的垃圾回收器。
除此之外,PHP将使用比更仔细编写的C / C++等效物更多的内存。
1024x1024 整数数组的内存使用情况:
- 标准阵列:218,756,848
- SplFixedArray: 92,914,208
测量公式为memory_get_peak_usage()
$array = new SplFixedArray(1024 * 1024); // array();
for ($i = 0; $i < 1024 * 1024; ++$i)
$array[$i] = 0;
echo memory_get_peak_usage();
请注意,C 中使用 64 位整数的相同数组将为 8M。
正如其他人所建议的那样,您可以将数据打包到一个字符串中。这更慢,但内存效率更高。如果使用8位值,那非常简单:
$x = str_repeat(chr(0), 1024*1024);
$x[$i] = chr($v & 0xff); // store value $v into $x[$i]
$v = ord($x[$i]); // get value $v from $x[$i]
这里的内存只有大约1.5MB(也就是说,当考虑PHP的整个开销时,只有这个整数字符串数组)。
为了好玩,我创建了一个简单的基准测试,创建1024x1024 8位整数,然后循环浏览它们一次。所有打包的版本都使用,以便用户代码看起来相同。ArrayAccess
mem write read
array 218M 0.589s 0.176s
packed array 32.7M 1.85s 1.13s
packed spl array 13.8M 1.91s 1.18s
packed string 1.72M 1.11s 1.08s
打包的数组使用本机 64 位整数(仅打包 7 个字节以避免处理有符号数据)和使用的打包字符串和 。显然,实现细节和计算机规格会对事情产生一些影响,但我希望你能得到类似的结果。ord
chr
因此,虽然数组的速度提高了6倍,但它也使用了125倍的内存作为下一个最佳选择:打包字符串。显然,如果您内存不足,速度无关紧要。(当我直接使用没有类的打包字符串时,它们只比本机数组慢3倍。ArrayAccess
简而言之,总而言之,如果速度有任何问题,我会使用纯PHP以外的其他东西来处理这些数据。