web-dev-qa-db-fra.com

Python 2.6 Performances de décodage JSON

J'utilise le module json dans Python 2.6 pour charger et décoder les fichiers JSON. Cependant, j'obtiens actuellement des performances plus lentes que prévu. J'utilise un cas de test qui est de 6 Mo et json.loads() prend 20 secondes.

Je pensais que le module json avait du code natif pour accélérer le décodage?

Comment vérifier si celui-ci est utilisé?

À titre de comparaison, j'ai téléchargé et installé le module python-cjson Et cjson.decode() prend 1 seconde pour le même scénario de test.

Je préfère utiliser le module JSON fourni avec Python 2.6 pour que les utilisateurs de mon code ne soient pas tenus d'installer des modules supplémentaires.

(Je développe sur Mac OS X, mais j'obtiens un résultat similaire sur Windows XP.)

45
James Austin

Il peut varier selon la plate-forme, mais le module json intégré est basé sur simplejson , sans compter les accélérations C. J'ai trouvé que simplejson était aussi rapide que python-cjson de toute façon, donc je le préfère car il a évidemment la même interface que le intégré.

try:
    import simplejson as json
except ImportError:
    import json

Il me semble que c'est le meilleur idiome pendant un certain temps, ce qui donne les performances lorsqu'elles sont disponibles tout en étant compatible avec l'avenir.

23
A. Coady

La nouvelle Yajl - Yet Another JSON Library est très rapide.

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

Vous pouvez comparer les bibliothèques vous-même .

Mise à jour: ltraJSON est encore plus rapide.

30
Ivo Danihelka

J'analysais le même fichier 10x. La taille du fichier était de 1 856 944 octets.

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

Je ne sais pas pourquoi les chiffres sont disproportionnés par rapport à vos résultats. Je suppose, des bibliothèques plus récentes?

17
Tomas

jetez un œil à UltraJSON https://github.com/esnme/ultrajson

ici mon test (code de: https://Gist.github.com/lightcatcher/1136415 )

plate-forme: 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
14
TONy.W

Pour ceux qui analysent la sortie d'une demande à l'aide du package de demandes, par exemple:

res = requests.request(...)

text = json.loads(res.text)

Cela peut être très lent pour un contenu de réponse plus important, disons ~ 45 secondes pour 6 Mo sur mon MacBook 2017. Elle n'est pas causée par un analyseur json lent, mais plutôt par une lente détermination du jeu de caractères par l'appel res.text.

Vous pouvez résoudre ce problème en définissant le jeu de caractères avant d'appeler res.text et en utilisant le package cchardet (voir aussi ici ):

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

Cela rend l'analyse du texte json presque instantanée!

3
ganzpopp

En regardant dans mon installation de Python 2.6.1 sur Windows, le paquetage json charge le _json module, qui est intégré à l'exécution. C source pour le json speedups le module est ici .

>>> import _json
>>> _json
<module '_json' (built-in)>
>>> print _json.__doc__
json speedups
>>> dir(_json)
['__doc__', '__name__', '__package__', 'encode_basestring_ascii', 'scanstring']
>>> 
2
gimel

Même si _json est disponible, j'ai remarqué que le décodage json est très lent sur CPython 2.6.6. Je n'ai pas comparé avec d'autres implémentations, mais je suis passé à la manipulation de chaînes lorsque vous êtes à l'intérieur de boucles critiques pour les performances.

1
Tobu