Saltar al contenido

Optimización de memoria en PHP array

La guía paso a paso o código que hallarás en este post es la resolución más eficiente y efectiva que hallamos a esta duda o problema.

Solución:

Si quieres un indexado real array, utilice SplFixedArray. Utiliza menos memoria. Además, PHP 5.3 tiene un recolector de basura mucho mejor.

Aparte de eso, PHP usará más memoria que un equivalente C/C++ escrito con más cuidado.

Uso de memoria para enteros de 1024×1024 array:

  • Estándar array: 218.756.848
  • Array SplFixed: 92,914,208

medido por 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();

Tenga en cuenta que el mismo array en C usando enteros de 64 bits sería 8M.

Como han sugerido otros, puede empaquetar los datos en un string. Esto es más lento pero mucho memoria más eficiente. Si usa valores de 8 bits, es muy fácil:

$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]

Aquí la memoria solo será de aproximadamente 1,5 MB (es decir, al considerar la sobrecarga total de PHP con solo este número entero string array).

Por diversión, creé un punto de referencia simple para crear enteros de 8 bits de 1024x1024 y luego recorrerlos una vez. Las versiones empaquetadas todas usadas ArrayAccess para que el código de usuario tuviera el mismo aspecto.

                   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

Las matrices empaquetadas usaban enteros nativos de 64 bits (solo empaquetaban 7 bytes para evitar tener que lidiar con datos firmados) y las matrices empaquetadas string usado ord y chr. Obviamente, los detalles de implementación y las especificaciones de la computadora afectarán un poco las cosas, pero espero que obtenga resultados similares.

Así que mientras el array era 6 veces más rápido, también usaba 125 veces la memoria como la siguiente mejor alternativa: cadenas empaquetadas. Obviamente, la velocidad es irrelevante si te estás quedando sin memoria. (Cuando usé cadenas empaquetadas directamente sin un ArrayAccess clase, eran solo 3 veces más lentos que los arreglos nativos).

En resumen, para resumir, usaría algo que no sea PHP puro para procesar estos datos si la velocidad es motivo de preocupación.

Además de la respuesta aceptada y las sugerencias en los comentarios, me gustaría sugerir PHP Judy array implementación.

Las pruebas rápidas mostraron resultados interesantes. Un array con 1 millón de entradas usando PHP regular array la estructura de datos ocupa ~200 MB. SplFixedArray usa alrededor de 90 megabytes. Judy usa 8 megas. La compensación está en el rendimiento, Judy tarda aproximadamente el doble de tiempo que php normal array implementación.

Un poco tarde para la fiesta, pero si tienes una multidimensional array puede ahorrar una gran cantidad de RAM cuando almacena el completo array como json.

$array = [];

$data = [];
$data["a"] = "hello";
$data["b"] = "world";

para almacenar esto array Solo usa:

$array[] = json_encode($data);

en lugar de

$array[] = $data;

Si desea recuperar el arrry, simplemente use algo como:

$myData = json_decode($array[0], true);

tuve un gran array con 275.000 juegos y ahorró alrededor del 36% del consumo de RAM.

EDITAR: Encontré una mejor manera, cuando comprimes el json string:

$array[] = gzencode(json_encode($data));

y descomprímelo cuando lo necesites:

$myData = json_decode(gzdecode($array[0], true));

Esto me ahorró casi el 75 % del uso máximo de RAM.

Aquí puedes ver las reseñas y valoraciones de los lectores

Te invitamos a añadir valor a nuestra información contribuyendo tu experiencia en las críticas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *