如果你想要一个真正的索引数组,可以使用 SplFixedArray。它使用的内存更少。此外,PHP 5.3拥有更好的垃圾回收器。
除此之外,PHP将比一个更仔细编写的C/C++等价物使用更多的内存。
1024x1024个整数的数组的内存使用情况:
- 标准数组:218,756,848
- SplFixedArray:92,914,208
由memory_get_peak_usage()
测量得出。
$array = new SplFixedArray(1024 * 1024);
for ($i = 0; $i < 1024 * 1024; ++$i)
$array[$i] = 0;
echo memory_get_peak_usage();
请注意,使用64位整数的C中相同的数组将为8M。
正如其他人建议的那样,您可以将数据打包到字符串中。这样做速度较慢,但内存效率要高得多。如果使用8位值,这很容易:
$x = str_repeat(chr(0), 1024*1024);
$x[$i] = chr($v & 0xff);
$v = ord($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倍的内存。如果你的内存不足,速度就无关紧要了。(当我直接使用压缩字符串而没有使用ArrayAccess
类时,它们只比本机数组慢3倍。)
简而言之,总结一下,如果速度很重要,我建议使用除纯PHP以外的其他工具来处理这些数据。
$x[1] = 2;
也会带着大量额外的东西。 - Marc Bpack()
来处理二进制字符串。但那并不是真正更快;只是节省了两倍的内存。(在PHP中只能做到这么多;) - mario