В моем PHP script мне нужно создать массив из целых чисел > 600k. К сожалению, для моих веб-серверов memory_limit
установлено значение 32M, поэтому при инициализации массива script прерывается с сообщением
Неустранимая ошибка: Разрешенный размер памяти из 33554432 байт исчерпан (попытался выделить 71 байт) в /home/www/myaccount/html/mem_test.php в строке 8
Мне известно о том, что PHP не сохраняет значения массива как простые целые числа, а скорее как zvalues, которые намного больше, чем простое целочисленное значение (8 байтов на моей 64-битной системе). Я написал небольшой script, чтобы оценить, сколько памяти использует каждая запись массива, и получается, что это довольно точно 128 байт. 128!!! Мне нужно было бы > 73M только для хранения массива. К сожалению, веб-сервер не находится под моим контролем, поэтому я не могу увеличить memory_limit
.
Мой вопрос в том, есть ли в PHP возможность создать структуру, подобную массиву, которая использует меньше памяти. Мне не нужна эта структура, чтобы быть ассоциативной (достаточно простого доступа к индексу). Также не требуется динамическое изменение размера - я точно знаю, насколько велика будет массив. Кроме того, все элементы будут одного типа. Как хороший старый C-массив.
Edit: Таким образом deceze решение работает готово с 32-разрядными целыми числами. Но даже если вы используете 64-битную систему, pack(), похоже, не поддерживает 64-битные целые числа. Чтобы использовать 64-битные целые числа в моем массиве, я применил некоторые манипуляции с битами. Возможно, нижеприведенные фрагменты помогут кому-то:
function push_back(&$storage, $value)
{
// split the 64-bit value into two 32-bit chunks, then pass these to pack().
$storage .= pack('ll', ($value>>32), $value);
}
function get(&$storage, $idx)
{
// read two 32-bit chunks from $storage and glue them back together.
return (current(unpack('l', substr($storage, $idx * 8, 4)))<<32 |
current(unpack('l', substr($storage, $idx * 8+4, 4))));
}