如果你想要一个真正的索引数组,使用
SplFixedArray.它使用较少的内存。另外PHP 5.3有一个更好的垃圾收集器。
除此之外,PHP将比使用更精心编写的C/C++等效文件使用更多的内存。
1024×1024整数数组的内存使用量:
>标准数组: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();
请注意,使用64位整数的C中的相同数组将为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的整个开销时)。
为了乐趣,我创建了一个创建1024×1024个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倍时,它也使用了125x的内存作为下一个最佳选择:打包字符串。显然,如果你的内存不足,速度是无关紧要的。 (当我直接使用没有ArrayAccess类的打包字符串时,它们的速度比本机数组慢3倍)
总之,总而言之,如果速度有任何疑问,我将使用除纯PHP之外的其他内容来处理这些数据。