serialize - ¿Cuáles son las diferencias entre los módulos json y simple json de Python?
simplejson python install (12)
He visto muchos proyectos utilizando el módulo simplejson
lugar del módulo json
de la biblioteca estándar. Además, hay muchos módulos diferentes de simplejson
. ¿Por qué utilizar estas alternativas, en lugar de la que está en la Biblioteca Estándar?
Algunos valores se serializan de forma diferente entre simplejson y json.
Notablemente, las instancias de collections.namedtuple
se serializan como arreglos de json
pero como objetos de simplejson
. Puede anular este comportamiento pasando namedtuple_as_object=False
a simplejson.dump
, pero por defecto los comportamientos no coinciden.
>>> import collections, simplejson, json
>>> TupleClass = collections.namedtuple("TupleClass", ("a", "b"))
>>> value = TupleClass(1, 2)
>>> json.dumps(value)
''[1, 2]''
>>> simplejson.dumps(value)
''{"a": 1, "b": 2}''
>>> simplejson.dumps(value, namedtuple_as_object=False)
''[1, 2]''
Aquí está (una comparación ahora desactualizada) de las bibliotecas Python json:
Comparando módulos JSON para Python ( enlace de archivo )
Independientemente de los resultados de esta comparación, debe usar la biblioteca estándar json si está en Python 2.6. Y ... también podría usar simplejson de otra manera.
El módulo json
incorporado se incluyó en Python 2.6. Cualquier proyecto que admita versiones de Python <2.6 debe tener un respaldo. En muchos casos, esa alternativa es simplejson
.
El módulo simplejson es simplemente 1,5 veces más rápido que json (en mi computadora, con simplejson 2.1.1 y Python 2.7 x86).
Si lo desea, puede probar el punto de referencia: http://abral.altervista.org/jsonpickle-bench.zip En mi PC, simplejson es más rápido que cPickle. Me gustaría conocer también tus puntos de referencia!
Probablemente, como dijo Coady, la diferencia entre simplejson y json es que simplejson incluye _speedups.c. Entonces, ¿por qué los desarrolladores de python no usan simplejson?
En python3, si tienes una cadena de b''bytes''
, con json
tienes que .decode()
el contenido antes de poder cargarlo. simplejson
se encarga de esto, así que simplemente puedes hacer simplejson.loads(byte_string)
.
He estado comparando json, simplejson y cjson.
- cjson es el más rápido
- simplejson está casi a la par con cjson
- json es aproximadamente 10x más lento que simplejson
$ python test_serialization_speed.py
--------------------
Encoding Tests
--------------------
Encoding: 100000 x {''m'': ''asdsasdqwqw'', ''t'': 3}
[ json] 1.12385 seconds for 100000 runs. avg: 0.011239ms
[simplejson] 0.44356 seconds for 100000 runs. avg: 0.004436ms
[ cjson] 0.09593 seconds for 100000 runs. avg: 0.000959ms
Encoding: 10000 x {''m'': [[''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19], [''0'', 1, ''2'', 3, ''4'', 5, ''6'', 7, ''8'', 9, ''10'', 11, ''12'', 13, ''14'', 15, ''16'', 17, ''18'', 19]], ''t'': 3}
[ json] 7.76628 seconds for 10000 runs. avg: 0.776628ms
[simplejson] 0.51179 seconds for 10000 runs. avg: 0.051179ms
[ cjson] 0.44362 seconds for 10000 runs. avg: 0.044362ms
--------------------
Decoding Tests
--------------------
Decoding: 100000 x {"m": "asdsasdqwqw", "t": 3}
[ json] 3.32861 seconds for 100000 runs. avg: 0.033286ms
[simplejson] 0.37164 seconds for 100000 runs. avg: 0.003716ms
[ cjson] 0.03893 seconds for 100000 runs. avg: 0.000389ms
Decoding: 10000 x {"m": [["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19], ["0", 1, "2", 3, "4", 5, "6", 7, "8", 9, "10", 11, "12", 13, "14", 15, "16", 17, "18", 19]], "t": 3}
[ json] 37.26270 seconds for 10000 runs. avg: 3.726270ms
[simplejson] 0.56643 seconds for 10000 runs. avg: 0.056643ms
[ cjson] 0.33007 seconds for 10000 runs. avg: 0.033007ms
Me encontré con esta pregunta mientras buscaba instalar simplejson para Python 2.6. Necesitaba usar el ''object_pairs_hook'' de json.load () para cargar un archivo json como OrderedDict. Al estar familiarizado con las versiones más recientes de Python, no me di cuenta de que el módulo json para Python 2.6 no incluye el ''object_pairs_hook'', así que tuve que instalar simplejson para este propósito. Por experiencia personal, es por eso que uso simplejson en lugar del módulo json estándar.
Otra razón por la que los proyectos usan simplejson es que el json integrado originalmente no incluía sus aceleraciones de C, por lo que la diferencia de rendimiento era notable.
Tengo que estar en desacuerdo con las otras respuestas: la biblioteca json
incorporada (en Python 2.7) no es necesariamente más lenta que simplejson
. Tampoco tiene este molesto error de Unicode .
Aquí hay un simple punto de referencia:
import json
import simplejson
from timeit import repeat
NUMBER = 100000
REPEAT = 10
def compare_json_and_simplejson(data):
"""Compare json and simplejson - dumps and loads"""
compare_json_and_simplejson.data = data
compare_json_and_simplejson.dump = json.dumps(data)
assert json.dumps(data) == simplejson.dumps(data)
result = min(repeat("json.dumps(compare_json_and_simplejson.data)", "from __main__ import json, compare_json_and_simplejson",
repeat = REPEAT, number = NUMBER))
print " json dumps {} seconds".format(result)
result = min(repeat("simplejson.dumps(compare_json_and_simplejson.data)", "from __main__ import simplejson, compare_json_and_simplejson",
repeat = REPEAT, number = NUMBER))
print "simplejson dumps {} seconds".format(result)
assert json.loads(compare_json_and_simplejson.dump) == data
result = min(repeat("json.loads(compare_json_and_simplejson.dump)", "from __main__ import json, compare_json_and_simplejson",
repeat = REPEAT, number = NUMBER))
print " json loads {} seconds".format(result)
result = min(repeat("simplejson.loads(compare_json_and_simplejson.dump)", "from __main__ import simplejson, compare_json_and_simplejson",
repeat = REPEAT, number = NUMBER))
print "simplejson loads {} seconds".format(result)
print "Complex real world data:"
COMPLEX_DATA = {''status'': 1, ''timestamp'': 1362323499.23, ''site_code'': ''testing123'', ''remote_address'': ''212.179.220.18'', ''input_text'': u''ny monday for less than /u20aa123'', ''locale_value'': ''UK'', ''eva_version'': ''v1.0.3286'', ''message'': ''Successful Parse'', ''muuid1'': ''11e2-8414-a5e9e0fd-95a6-12313913cc26'', ''api_reply'': {"api_reply": {"Money": {"Currency": "ILS", "Amount": "123", "Restriction": "Less"}, "ProcessedText": "ny monday for less than //u20aa123", "Locations": [{"Index": 0, "Derived From": "Default", "Home": "Default", "Departure": {"Date": "2013-03-04"}, "Next": 10}, {"Arrival": {"Date": "2013-03-04", "Calculated": True}, "Index": 10, "All Airports Code": "NYC", "Airports": "EWR,JFK,LGA,PHL", "Name": "New York City, New York, United States (GID=5128581)", "Latitude": 40.71427, "Country": "US", "Type": "City", "Geoid": 5128581, "Longitude": -74.00597}]}}}
compare_json_and_simplejson(COMPLEX_DATA)
print "/nSimple data:"
SIMPLE_DATA = [1, 2, 3, "asasd", {''a'':''b''}]
compare_json_and_simplejson(SIMPLE_DATA)
Y los resultados en mi sistema (Python 2.7.4, Linux de 64 bits):
Datos complejos del mundo real:
json vuelca 1.56666707993 segundos
volcado simplejson 2.25638604164 segundos
json carga 2.71256899834 segundos
simplejson carga 1.29233884811 segundosDatos simples:
json vuelca 0,370109081268 segundos
volcados simplesjson 0.574181079865 segundos
json carga 0.422876119614 segundos
simplejson carga 0.270955085754 segundos
Para el dumping, json
es más rápido que simplejson
. Para cargar, simplejson
es más rápido.
Como actualmente estoy creando un servicio web, dumps()
es más importante, y siempre es preferible usar una biblioteca estándar.
Además, cjson
no se actualizó en los últimos 4 años, por lo que no lo tocaría.
Todas estas respuestas no son muy útiles porque son sensibles al tiempo .
Después de investigar por mi cuenta, descubrí que simplejson
es más rápido que el incorporado, si lo mantienes actualizado a la última versión.
pip/easy_install
quería instalar 2.3.2 en ubuntu 12.04, pero después de descubrir la última versión de simplejson
es en realidad 3.3.0, así que lo actualicé y volví a realizar las pruebas de tiempo.
-
simplejson
es aproximadamente 3 veces más rápido que eljson
incorporado en cargas -
simplejson
es aproximadamente un 30% más rápido que eljson
integrado en los vertederos
Renuncia:
Las declaraciones anteriores están en python-2.7.3 y simplejson 3.3.0 (con aceleraciones de c) Y para asegurarme de que mi respuesta no sea sensible al tiempo, debe realizar sus propias pruebas para verificar, ya que varía mucho entre las versiones; No hay una respuesta fácil que no sea sensible al tiempo.
Cómo saber si las aceleraciones de C están habilitadas en simplejson:
import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, ''_speedups'', False))
ACTUALIZACIÓN: Recientemente encontré una biblioteca llamada ujson que se está ejecutando ~ 3 veces más rápido que simplejson
con algunas pruebas básicas.
Una incompatibilidad API que encontré, con Python 2.7 vs simplejson 3.3.1 está en si la salida produce objetos str o unicode. p.ej
>>> from json import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{u''a'': u''b''}
vs
>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{''a'': ''b''}
Si la preferencia es usar simplejson, entonces esto se puede abordar mediante la coacción de la cadena del argumento a unicode, como en:
>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode(unicode("""{ "a":"b" }""", "utf-8"))
{u''a'': u''b''}
La coerción requiere conocer el conjunto de caracteres original, por ejemplo:
>>> jd.decode(unicode("""{ "a": "ξηθννββωφρες" }"""))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: ''ascii'' codec can''t decode byte 0xce in position 8: ordinal not in range(128)
Este es el problema de no arreglarse 40
json
is simplejson
json
, añadido a la stdlib. Pero como json
se agregó en 2.6, simplejson
tiene la ventaja de trabajar en más versiones de Python (2.4+).
simplejson
también se actualiza con más frecuencia que Python, por lo que si necesita (o desea) la última versión, es mejor usar simplejson
, si es posible.
Una buena práctica, en mi opinión, es usar una u otra como alternativa.
try:
import simplejson as json
except ImportError:
import json