web-dev-qa-db-fra.com

Quelles sont les différences entre les modules json et simplejson Python?

J'ai vu de nombreux projets utilisant le module simplejson au lieu du module json du Bibliothèque standard. En outre, il existe de nombreux modules simplejson. Pourquoi utiliser ces alternatives au lieu de celles de la bibliothèque standard?

367
Lakshman Prasad

jsonestsimplejson, ajouté à la bibliothèque standard. Mais depuis que json a été ajouté dans la version 2.6, simplejson a l’avantage de travailler sur plusieurs versions de Python (2.4+).

simplejson est également mis à jour plus fréquemment que Python. Par conséquent, si vous avez besoin (ou souhaitez) de la version la plus récente, il est préférable d'utiliser simplejson lui-même, si possible.

À mon avis, une bonne pratique consiste à utiliser l’une ou l’autre comme solution de rechange.

try:
    import simplejson as json
except ImportError:
    import json
375
Devin Jeanpierre

Je ne suis pas d'accord avec les autres réponses: la bibliothèque intégrée json (dans Python 2.7) n'est pas nécessairement plus lente que simplejson. Il n'a pas non plus ce bogue unicode ennuyeux .

Voici un repère simple:

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)

Et les résultats sur mon système (Python 2.7.4, Linux 64 bits):

Données du monde réel complexes:
Json affiche 1,56666707993 secondes
simplejson vidages 2,25638604164 secondes
json charge 2.71256899834 secondes
simplejson charge 1.29233884811 secondes

Données simples:
json dumps 0.370109081268 secondes
simplejson dumps 0.574181079865 secondes
json charge 0.422876119614 secondes
simplejson charge en 0.270955085754 secondes

Pour le dumping, json est plus rapide que simplejson. Pour le chargement, simplejson est plus rapide.

Étant donné que je construis actuellement un service Web, dumps() est plus important et l'utilisation d'une bibliothèque standard est toujours préférable.

De plus, cjson n'a pas été mis à jour au cours des 4 dernières années, je ne le toucherais donc pas.

81
Tal Weiss

Toutes ces réponses ne sont pas très utiles car elles sont sensibles au temps .

Après avoir effectué mes propres recherches, j’ai trouvé que simplejson est en effet plus rapide que l’intégré si vous le mettez à jour avec la dernière version.

pip/easy_install voulait installer la version 2.3.2 sur Ubuntu 12.04, mais après avoir découvert la dernière version de simplejson est en fait la version 3.3.0, je l'ai donc mise à jour et j'ai relancé les tests de temps.

  • simplejson est environ 3 fois plus rapide que la fonction intégrée json à des charges
  • simplejson est environ 30% plus rapide que la fonction intégrée json aux décharges

Avertissement:

Les instructions ci-dessus sont en python-2.7.3 et simplejson 3.3.0 (avec c accélérations). Et pour être sûr que ma réponse n’est pas sensible au temps, vous devez exécuter vos propres tests à vérifier car cela varie beaucoup d'une version à l'autre; il n'y a pas de réponse facile qui ne soit pas sensible au temps.

Comment savoir si les accélérations C sont activées dans simplejson:

import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, '_speedups', False))

UPDATE: Je suis récemment tombé sur une bibliothèque appelée json qui exécute ~ 3x plus vite que simplejson avec quelques bases tests.

26
notbad.jpeg

J'ai comparé json, simplejson et cjson.

  • cjson est le plus rapide
  • simplejson est presque à égalité avec cjson
  • jSON est environ 10 fois plus lent que SimpleJson

http://pastie.org/1507411 :

$ 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
21
Chris

Certaines valeurs sont sérialisées différemment entre simplejson et json.

Notamment, les instances de collections.namedtuple sont sérialisées en tant que tableaux par json mais en tant qu'objets par simplejson. Vous pouvez remplacer ce comportement en passant namedtuple_as_object=False à simplejson.dump, mais par défaut, les comportements ne correspondent pas.

>>> 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]'
9
pfhayes

Une incompatibilité d'API que j'ai trouvée, avec Python 2.7 vs simplejson 3.3.1 indique si la sortie génère des objets str ou unicode. par exemple.

>>> from json import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{u'a': u'b'}

contre

>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{'a': 'b'}

Si vous préférez utiliser simplejson, vous pouvez résoudre ce problème en contraignant l'argument à unicode, comme dans l'exemple suivant:

>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode(unicode("""{ "a":"b" }""", "utf-8"))
{u'a': u'b'}

La coercition nécessite de connaître le jeu de caractères d'origine, par exemple:

>>> 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)

C'est la solution qui ne va pas numéro 4

7
jjc

Le module intégré json a été inclus dans Python 2.6. Tous les projets qui prennent en charge les versions de Python <2.6 doivent avoir un repli. Dans de nombreux cas, ce repli est simplejson.

5
thedz

Une autre raison pour laquelle les projets utilisent simplejson est que le JSON intégré n’incluait pas à l’origine les accélérations C, la différence de performances était donc perceptible.

5
A. Coady

Voici une comparaison (maintenant obsolète) des bibliothèques Python json:

Comparaison des modules JSON pour Python ( lien d'archive )

Quels que soient les résultats de cette comparaison, vous devez utiliser la bibliothèque standard json si vous êtes sur Python 2.6. Et .. pourrait aussi bien utiliser simplejson autrement.

4
Van Gale

En python3, si vous utilisez une chaîne de b'bytes', avec json, vous devez .decode() le contenu avant de pouvoir le charger. simplejson prend soin de cela pour que vous puissiez simplement faire simplejson.loads(byte_string).

2
voidnologo

le module simplejson est tout simplement 1,5 fois plus rapide que json (sur mon ordinateur, avec simplejson 2.1.1 et Python 2,7 x86).

Si vous le souhaitez, vous pouvez essayer le repère: http://abral.altervista.org/jsonpickle-bench.Zip Sur mon PC, simplejson est plus rapide que cPickle. J'aimerais aussi connaître vos repères!

Probablement, comme dit Coady, la différence entre simplejson et json est que simplejson inclut _speedups.c. Alors, pourquoi les développeurs python n'utilisent-ils pas simplejson?

2
Jeko

Je suis tombé sur cette question alors que je cherchais à installer simplejson pour Python 2.6. J'avais besoin d'utiliser le 'object_pairs_hook' de json.load () afin de charger un fichier json en tant que OrderedDict. Connaissant bien les versions plus récentes de Python, je ne savais pas que le module json pour Python 2.6 n'incluait pas 'object_pairs_hook'. J'ai donc dû installer simplejson à cette fin. De par mon expérience personnelle, c’est la raison pour laquelle j’utilise simplejson par opposition au module JSON standard.

0
BeeLabeille