Python 2.6 JSON deencoding de rendimiento

Estoy usando el módulo json en Python 2.6 para cargar y decodificar archivos JSON. Sin embargo, actualmente estoy recibiendo un rendimiento más lento de lo esperado. Estoy usando un caso de prueba que tiene un tamaño de 6MB y json.loads() está tomando 20 segundos.

Pensé que el módulo json tenía algún código nativo para acelerar la deencoding?

¿Cómo verifico si se está utilizando?

Como comparación, descargué e instalé el módulo python-cjson , y cjson.decode() está tomando 1 segundo para el mismo caso de prueba.

Prefiero usar el módulo JSON provisto con Python 2.6 para que los usuarios de mi código no tengan que instalar módulos adicionales.

(Estoy desarrollando en Mac OS X, pero obtengo un resultado similar en Windows XP).

Puede variar según la plataforma, pero el módulo json integrado se basa en simplejson , sin incluir las aceleraciones de C. De todas formas, me parece que simplejson es tan rápido como python-cjson, así que lo prefiero, ya que obviamente tiene la misma interfaz que la incorporada.

 try: import simplejson as json except ImportError: import json 

Me parece que es el mejor modismo por un tiempo, que ofrece el rendimiento cuando está disponible y es compatible con los usuarios.

El nuevo Yajl – Yet Another JSON Library es muy rápido.

 yajl serialize: 0.180 deserialize: 0.182 total: 0.362 simplejson serialize: 0.840 deserialize: 0.490 total: 1.331 stdlib json serialize: 2.812 deserialize: 8.725 total: 11.537 

Puedes comparar las bibliotecas tú mismo .

Actualización: UltraJSON es aún más rápido.

Estaba analizando el mismo archivo 10x. El tamaño del archivo era 1,856,944 bytes.

Python 2.6:

 yajl serialize: 0.294 deserialize: 0.334 total: 0.627 cjson serialize: 0.494 deserialize: 0.276 total: 0.769 simplejson serialize: 0.554 deserialize: 0.268 total: 0.823 stdlib json serialize: 3.917 deserialize: 17.508 total: 21.425 

Python 2.7:

 yajl serialize: 0.289 deserialize: 0.312 total: 0.601 cjson serialize: 0.232 deserialize: 0.254 total: 0.486 simplejson serialize: 0.288 deserialize: 0.253 total: 0.540 stdlib json serialize: 0.273 deserialize: 0.256 total: 0.528 

No estoy seguro de por qué los números son desproporcionados de sus resultados. Supongo, bibliotecas más nuevas?

Eche un vistazo a UltraJSON https://github.com/esnme/ultrajson

aquí mi prueba (código de: https://gist.github.com/lightcatcher/1136415 )

Plataforma: OS X 10.8.3 MBP 2.2 GHz Intel Core i7

JSON:

simplejson == 3.1.0

python-cjson == 1.0.5

jsonlib == 1.6.1

ujson == 1.30

yajl == 0.3.5

 JSON Benchmark 2.7.2 (default, Oct 11 2012, 20:14:37) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] ----------------------------- ENCODING simplejson: 0.293394s cjson: 0.461517s ujson: 0.222278s jsonlib: 0.428641s json: 0.759091s yajl: 0.388836s DECODING simplejson: 0.556367s cjson: 0.42649s ujson: 0.212396s jsonlib: 0.265861s json: 0.365553s yajl: 0.361718s 

Para aquellos que están analizando la salida de una solicitud utilizando el paquete de solicitudes, por ejemplo:

 res = requests.request(...) text = json.loads(res.text) 

Esto puede ser muy lento para contenidos de respuesta más grandes, digamos ~ 45 segundos para 6 MB en mi MacBook 2017. No es causado por un analizador lento de json, sino por una determinación lenta del conjunto de caracteres por la llamada res.text.

Puede resolver esto configurando el conjunto de caracteres antes de llamar a res.text y usando el paquete cchardet (vea también aquí ):

 if res.encoding is None: res.encoding = cchardet.detect(res.content)['encoding'] 

¡Esto hace que el texto de respuesta json parsing sea casi instantáneo!

Mirando en mi instalación de Python 2.6.1 en windows, el paquete json carga el módulo _json , que está integrado en el tiempo de ejecución. C fuente C para el módulo json speedups está aquí .

 >>> import _json >>> _json  >>> print _json.__doc__ json speedups >>> dir(_json) ['__doc__', '__name__', '__package__', 'encode_basestring_ascii', 'scanstring'] >>> 

Aunque _json está disponible, he notado que la deencoding json es muy lenta en CPython 2.6.6. No he comparado con otras implementaciones, pero he cambiado a la manipulación de cadenas cuando estoy dentro de bucles críticos de rendimiento.