Ответ 1
Если вам нужен настоящий индексированный массив, используйте SplFixedArray. Он использует меньше памяти. Кроме того, PHP 5.3 имеет гораздо лучший сборщик мусора.
Кроме этого, ну, PHP будет использовать больше памяти, чем более тщательно написанный эквивалент 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.
Как и другие, вы можете упаковать данные в строку. Это медленнее, но much больше эффективности памяти. Если использовать 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,5 МБ (т.е. при рассмотрении всех накладных расходов PHP с помощью всего этого массива целых строк).
Для удовольствия от этого я создал простой тест создания 8-разрядных целых чисел 1024x1024, а затем прокручивал их один раз. Все упакованные версии использовали 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, для обработки этих данных, если скорость вызывает какое-либо беспокойство.