Necesito almacenar una matriz asociativa multidimensional de datos en un archivo plano para fines de almacenamiento en caché. De vez en cuando podría encontrar la necesidad de convertirlo a JSON para usarlo en mi aplicación web, pero la gran mayoría de las veces usaré la matriz directamente en PHP.
¿Sería más eficiente almacenar la matriz como JSON o como una matriz serializada PHP en este archivo de texto? He mirado alrededor y parece que en las versiones más recientes de PHP (5.3), en json_decode
realidad es más rápido que unserialize
.
Actualmente me estoy inclinando hacia el almacenamiento de la matriz como JSON, ya que siento que es más fácil de leer por un humano si es necesario, puede usarse tanto en PHP como en JavaScript con muy poco esfuerzo, y por lo que he leído, incluso podría ser más rápido de decodificar (sin embargo, no estoy seguro acerca de la codificación).
¿Alguien sabe de alguna trampa? ¿Alguien tiene buenos puntos de referencia para mostrar los beneficios de rendimiento de cualquiera de los métodos?
fuente
JSON_UNESCAPED_UNICODE
.json_encode
) y está promediando aproximadamente un 131% más rápido que la serialización ahora. Entonces, debe haber algunas mejoras bastante buenas para esa función en 5.4.x sobre 5.3.x. Específicamente, estoy ejecutando 5.4.24 en CentOS 6. Entonces, ¡yay para JSON!serialize() was roughly 35.04% faster than json_encode()
JSON es más simple y rápido que el formato de serialización de PHP y debe usarse a menos que :
json_decode()
:: "Esta función devolverá falso si los datos codificados con JSON son más profundos que 127 elementos".fuente
He escrito una entrada de blog sobre este tema:
" Caché una gran matriz: JSON, serializar o var_export? ". En esta publicación se muestra que serializar es la mejor opción para arreglos de tamaño pequeño a grande. Para matrices muy grandes (> 70 MB), JSON es la mejor opción.fuente
json_encode()
es aproximadamente 80% a 150% más rápido (realmente va arriba y abajo) queserialize()
, con aproximadamente 300 iteraciones. Pero cuando utilicé las matrices más pequeñas (array("teams" => array(1 => array(4 arrays of players), 2 => array(4 arrays of players)))
), probé con 750,000 iteraciones y en ese casoserialize()
es aproximadamente 6% a 10% más rápido. Mi función toma los tiempos promedio para todas las iteraciones y los compara. Podría publicarlo aquí como una de las respuestasTambién puede estar interesado en https://github.com/phadej/igbinary , que proporciona un 'motor' de serialización diferente para PHP.
Mis cifras de 'rendimiento' aleatorias / arbitrarias, usando PHP 5.3.5 en una plataforma de 64 bits muestran:
JSON
PHP nativo:
Igbinary:
Por lo tanto, es más rápido igbinary_serialize () e igbinary_unserialize () y usa menos espacio en disco.
Utilicé el código fillArray (0, 3) como el anterior, pero hice que las teclas de matriz sean cadenas más largas.
igbinary puede almacenar los mismos tipos de datos que la serialización nativa de PHP (así que no hay problema con los objetos, etc.) y puede decirle a PHP5.3 que lo use para el manejo de la sesión si así lo desea.
Ver también http://ilia.ws/files/zendcon_2010_hidden_features.pdf - específicamente diapositivas 14/15/16
fuente
Y acaba de probar la codificación y decodificación serializada y json, más el tamaño que tomará la cadena almacenada.
Podemos concluir que JSON codifica más rápido y da como resultado una cadena más pequeña, pero deserializar es más rápido para decodificar la cadena.
fuente
Si está almacenando información en caché que finalmente desea "incluir" en un momento posterior, puede intentar usar var_export . De esa forma, solo recibirás el golpe en "serializar" y no en "no serializar".
fuente
Aumenté la prueba para incluir el rendimiento de deserialización. Aquí están los números que obtuve.
Entonces, json parece ser más rápido para la codificación pero lento en la decodificación. Por lo tanto, podría depender de su aplicación y de lo que espera hacer más.
fuente
Muy buen tema y después de leer las pocas respuestas, quiero compartir mis experimentos sobre el tema.
Obtuve un caso de uso en el que se debe consultar una tabla "enorme" casi cada vez que hablo con la base de datos (no pregunte por qué, solo un hecho). El sistema de almacenamiento en caché de la base de datos no es apropiado ya que no almacenará en caché las diferentes solicitudes, así que pensé en los sistemas de almacenamiento en caché de php.
Lo intenté
apcu
pero no se ajustaba a las necesidades, la memoria no es lo suficientemente confiable en este caso. El siguiente paso fue almacenar en caché un archivo con serialización.La tabla tiene 14355 entradas con 18 columnas, esas son mis pruebas y estadísticas sobre la lectura del caché serializado:
JSON
Como todos dijeron, el mayor inconveniente con
json_encode
/json_decode
es que transforma todo en unaStdClass
instancia (u Objeto). Si necesita hacer un bucle, lo que probablemente hará es transformarlo en una matriz, y sí, aumenta el tiempo de transformaciónMsgpack
@hutch menciona msgpack . Bonito sitio web. Vamos a intentarlo, ¿de acuerdo?
Eso es mejor, pero requiere una nueva extensión; compilando a veces personas asustadas ...
IgBinary
@GingerDog menciona igbinary . Tenga en cuenta que lo configuré
igbinary.compact_strings=Off
porque me importa más leer interpretaciones que el tamaño de archivo.Mejor que el paquete de mensajes. Aún así, este también requiere compilación.
serialize
/ /unserialize
Mejores rendimientos que JSON, cuanto más grande es la matriz, más lento
json_decode
es, pero eso ya lo sabes.Esas extensiones externas están reduciendo el tamaño del archivo y parece genial en papel. Los números no mienten *. ¿Cuál es el punto de compilar una extensión si obtienes casi los mismos resultados que tendrías con una función PHP estándar?
También podemos deducir que, según sus necesidades, elegirá algo diferente a otra persona:
¡Eso es todo, otra comparación de métodos de serialización para ayudarlo a elegir uno!
* Probado con PHPUnit 3.7.31, php 5.5.10: solo decodificación con un disco duro estándar y una CPU de doble núcleo antigua: números promedio en 10 pruebas de casos de uso iguales, sus estadísticas pueden ser diferentes
fuente
json_decode($object, true)
, básicamente hará lo mismo(array) json_decode($object)
pero de manera recursiva, de modo que sería el mismo comportamiento y tendría un costo significativo en ambos casos. Tenga en cuenta que no he probado las diferencias de rendimiento entreStdClass
y,array
pero ese no es realmente el punto aquí.Parece que serializar es el que voy a usar por 2 razones:
Alguien señaló que unserialize es más rápido que json_decode y un caso de 'lectura' suena más probable que un caso de 'escritura'.
He tenido problemas con json_encode cuando tengo cadenas con caracteres UTF-8 no válidos. Cuando eso sucede, la cadena termina vacía y causa pérdida de información.
fuente
He probado esto muy a fondo en un hash múltiple bastante complejo y ligeramente anidado con todo tipo de datos (cadena, NULL, enteros), y serializar / deserializar terminó mucho más rápido que json_encode / json_decode.
La única ventaja que json tiene en mis pruebas es que es un tamaño 'empaquetado' más pequeño.
Estos se realizan en PHP 5.3.3, avíseme si desea más detalles.
Aquí están los resultados de las pruebas y luego el código para producirlos. No puedo proporcionar los datos de la prueba ya que revelaría información que no puedo dejar salir en la naturaleza.
fuente
También hice un pequeño punto de referencia. Mis resultados fueron los mismos. Pero necesito el rendimiento de decodificación. Donde me di cuenta, como algunas personas arriba mencionadas también,
unserialize
es más rápido quejson_decode
.unserialize
toma aproximadamente el 60-70% deljson_decode
tiempo. Entonces, la conclusión es bastante simple: cuando necesite rendimiento en la codificación, usejson_encode
, cuando necesite rendimiento en la decodificación, useunserialize
. Debido a que no puede fusionar las dos funciones, debe elegir dónde necesita más rendimiento.Mi punto de referencia en pseudo:
En promedio: unserialize ganó 96 veces más de 4 veces el json_decode. Con un promedio de aproximadamente 1.5ms sobre 2.5ms.
fuente
Antes de tomar su decisión final, tenga en cuenta que el formato JSON no es seguro para las matrices asociativas; en su lugar
json_decode()
, las devolverá como objetos:Salida es:
fuente
json_encode
era una matriz asociativa, puede forzarlo fácilmente a una matriz de la siguiente manera:$json = json_encode($some_assoc_array); $back_to_array = (array)json_decode($json);
También es bueno tener en cuenta que puede acceder a los objetos de la misma manera que las matrices en PHP, por lo que en un escenario típico, uno ni siquiera sabría la diferencia. Buen punto sin embargo!Primero, cambié el script para hacer más benchmarking (y también hacer 1000 ejecuciones en lugar de solo 1):
Usé esta compilación de PHP 7:
Y mis resultados fueron:
Así que claramente , serializar / unserialize es el más rápido método, mientras que json_encode / decodificación es el más portátil.
Si considera un escenario en el que lee / escribe datos serializados 10 veces o más de lo que necesita enviar o recibir de un sistema que no sea PHP, TODAVÍA es mejor usar serializar / deserializar y tener json_encode o json_decode antes de la serialización en términos de tiempo.
fuente
Mira los resultados aquí (perdón por el truco que pone el código PHP en el cuadro de código JS):
http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/
RESULTADOS:
serialize()
yunserialize()
ambos son significativamente más rápidos en PHP 5.4 en matrices de diferentes tamaños.Hice un script de prueba en datos del mundo real para comparar json_encode vs serialize y json_decode vs unserialize. La prueba se ejecutó en el sistema de almacenamiento en caché de un sitio de comercio electrónico en producción. Simplemente toma los datos que ya están en el caché, y prueba los tiempos para codificar / decodificar (o serializar / deserializar) todos los datos y los pongo en una tabla fácil de ver.
Ejecuté esto en un servidor de alojamiento compartido PHP 5.4.
Los resultados fueron muy concluyentes de que para estos conjuntos de datos grandes y pequeños, serializar y no serializar fueron los claros ganadores. En particular para mi caso de uso, json_decode y unserialize son los más importantes para el sistema de almacenamiento en caché. Unserialize fue casi un ganador ubicuo aquí. Por lo general, era de 2 a 4 veces (a veces 6 o 7 veces) tan rápido como json_decode.
Es interesante notar la diferencia en los resultados de @ peter-bailey.
Aquí está el código PHP utilizado para generar los resultados:
fuente
solo para su información: si desea serializar sus datos en algo fácil de leer y comprender como JSON pero con más compresión y mayor rendimiento, debe consultar el paquete de mensajes.
fuente
JSON es mejor si desea hacer una copia de seguridad de los datos y restaurarlos en una máquina diferente o mediante FTP.
Por ejemplo, con serializar si almacena datos en un servidor de Windows, descárguelos a través de FTP y restaure en uno de Linux, ya no podría funcionar debido a la codificación de caracteres, porque serializar almacena la longitud de las cadenas y en Unicode > La transcodificación UTF-8 de un carácter de 1 byte podría convertirse en 2 bytes de longitud, lo que ocasionaría la falla del algoritmo.
fuente
THX - para este código de referencia:
Mis resultados en la matriz que uso para la configuración son los siguientes: JSON codificado en 0.0031511783599854 segundos
PHP serializado en 0.0037961006164551 segundos
json_encode()
fue aproximadamente 20.47% más rápido queserialize()
JSON codificado en 0.0070841312408447 segundosPHP serializado en 0.0035839080810547 segundos
unserialize()
fue aproximadamente 97.66% más rápido quejson_encode()
Entonces, pruébelo con sus propios datos.
fuente
Si para resumir lo que dice la gente aquí, json_decode / encode parece más rápido que serializar / deserializar PERO Si hace var_dump, se cambia el tipo del objeto serializado. Si por alguna razón desea conservar el tipo, ¡vaya a serializar!
(intente, por ejemplo, stdClass vs array)
serializar / deserializar:
codificación / decodificación json
Como puede ver, json_encode / decode convierte todo a stdClass, lo que no es tan bueno, la información del objeto se perdió ... Así que decida según las necesidades, especialmente si no se trata solo de matrices ...
fuente
Te sugiero que uses Super Cache, que es un mecanismo de caché de archivos que no usará
json_encode
oserialize
. Es simple de usar y realmente rápido en comparación con otros mecanismos de caché PHP.https://packagist.org/packages/smart-php/super-cache
Ex:
fuente