Python 2.6 JSON performances de décodage
-
22-08-2019 - |
Question
J'utilise le module json
en Python 2.6 pour charger et décoder les fichiers JSON. Cependant, je suis actuellement devient plus lent que les performances attendues. J'utilise un test qui est 6MB en taille et json.loads()
prend 20 secondes.
Je pensais que le module json
avait un code natif pour accélérer le décodage?
Comment puis-je vérifier si cela est utilisé?
A titre de comparaison, j'ai téléchargé et installé le module python-cjson
et cjson.decode()
est de prendre 1 seconde pour le même cas de test.
Je préfère utiliser le module JSON fourni avec Python 2.6 afin que les utilisateurs de mon code ne sont pas tenus d'installer des modules supplémentaires.
(Je développe sur Mac OS X, mais j'obtenir un résultat similaire sous Windows XP).
La solution
Il peut varier selon la plate-forme, mais le module JSON est basé sur builtin simplejson , non y compris les accélérations C. Je l'ai trouvé simplejson être comme rapide que python-cjson de toute façon, donc je préfère depuis qu'il a évidemment la même interface que la fonction interne.
try:
import simplejson as json
except ImportError:
import json
Il me semble que c'est le meilleur langage pour un certain temps, ce qui donne les performances lorsqu'ils sont disponibles, tout en étant compatible en avant.
Autres conseils
Le nouveau Yajl -. Pourtant, une autre bibliothèque JSON 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 .
Mise à jour:. UltraJSON est encore plus rapide
je l'analyse syntaxique du même fichier 10x. Taille du fichier a été 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 de vos résultats. Je suppose que, de nouvelles bibliothèques?
jetez un oeil UltraJSON https://github.com/esnme/ultrajson
ici mon test (code à partir 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
1,30 ujson ==
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
Pour ceux qui analysez sortie d'une demande à l'aide du paquet demandes, par exemple:.
res = requests.request(...)
text = json.loads(res.text)
Cela peut être très lent pour le contenu de réponse plus gros, disons ~ 45 secondes pour 6 Mo sur mon MacBook 2017. Il ne provient pas d'un analyseur de JSON lent, mais par une détermination du jeu de caractères lent par l'appel res.text.
Vous pouvez résoudre ce problème en réglant le jeu de caractères avant vous appelez res.text, et en utilisant le paquet cchardet (voir aussi ici ):
if res.encoding is None:
res.encoding = cchardet.detect(res.content)['encoding']
Cela rend le texte de réponse JSON analyse syntaxique presque instantanée!
Recherche dans l'installation de Python 2.6.1 sur Windows, le paquet json
charge le module _json
, qui est intégré dans le moteur d'exécution. source C
pour le module json speedups
est .
>>> import _json
>>> _json
<module '_json' (built-in)>
>>> print _json.__doc__
json speedups
>>> dir(_json)
['__doc__', '__name__', '__package__', 'encode_basestring_ascii', 'scanstring']
>>>
Même si _json
est disponible, je l'ai remarqué 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îne lors de l'intérieur des boucles de performance critiques.