如果你想要一个真正的索引数组,使用SplFixedArray。它使用较少的内存。此外,PHP 5.3有一个更好的垃圾收集器。
除此之外,PHP将使用比更精心编写的C/C++等价物更多的内存。
内存使用1024×1024的整数数组:
- 标准阵列:218756848
- SplFixedArray:92914208
通过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与眼前这个整数字符串数组整个开销时)。
为了好玩,我创建了一个创建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以外的东西来处理这些数据。
数组在PHP中是真正的内存渴望(因为它们实际上是字典)。如果你可以放弃一些(很多!)的速度,你可以[伪造二进制数组像C](http://stackoverflow.com/questions/5505124/cheating-php-integers/5505643#5505643),也可以用于2D结构我猜。但是,也许你真的想调查[HipHop PHP到C++编译器](https://github.com/facebook/hiphop-php/wiki/)。 – mario 2011-06-13 21:25:37
PHP中的每个变量都有与之相关的开销。不仅变量的值必须被存储,而且变量的名字,类型等等......即使是一个简单的'$ x [1] = 2;'也有大量额外的东西在其后面。 – 2011-06-13 21:27:53
怎么样一个PHP扩展? – Bytemain 2011-06-13 21:32:25