Каковы различия между модулями Python json и simplejson? - PullRequest
363 голосов
/ 03 апреля 2009

Я видел много проектов, использующих модуль simplejson вместо модуля json из стандартной библиотеки. Также есть много разных simplejson модулей. Зачем использовать эти альтернативы вместо той, которая есть в стандартной библиотеке?

Ответы [ 12 ]

370 голосов
/ 03 апреля 2009

json равно simplejson, добавлено в stdlib. Но поскольку json был добавлен в версии 2.6, simplejson имеет преимущество работы с большим количеством версий Python (2.4+).

simplejson также обновляется чаще, чем Python, поэтому, если вам нужна (или вы хотите) последняя версия, лучше по возможности использовать simplejson, если возможно.

Хорошей практикой, на мой взгляд, является использование одного или другого в качестве запасного варианта.

try:
    import simplejson as json
except ImportError:
    import json
80 голосов
/ 21 апреля 2013

Я не согласен с другими ответами: встроенная библиотека json (в Python 2.7) не обязательно медленнее, чем simplejson. У этого также нет этой раздражающей ошибки юникода .

Вот простой тест:

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)

И результаты в моей системе (Python 2.7.4, Linux 64-bit):

Сложные данные реального мира:
JSON Dump 1.56666707993 секунд
дампы просто джайсон 2.25638604164 секунд
JSON загружает 2,71256899834 секунд
simplejson загружает 1,29233884811 секунд

Простые данные:
json dumps 0.370109081268 секунд
simplejson dumps 0.574181079865 секунд
JSON загружает 0,422876119614 секунд
simplejson загружает 0,270955085754 секунд

Для сброса json быстрее, чем simplejson. Для загрузки simplejson быстрее.

Поскольку я сейчас создаю веб-сервис, dumps() важнее - и всегда предпочтительнее использовать стандартную библиотеку.

Кроме того, cjson не обновлялся в течение последних 4 лет, поэтому я бы не стал его трогать.

24 голосов
/ 24 июля 2013

Все эти ответы не очень полезны, потому что они чувствительны ко времени .

Проведя свое собственное исследование, я обнаружил, что simplejson действительно быстрее встроенного, , если , вы обновляете его до последней версии.

pip/easy_install хотел установить 2.3.2 на Ubuntu 12.04, но после обнаружения последней версии simplejson на самом деле 3.3.0, поэтому я обновил ее и перезапустил тесты времени.

  • simplejson примерно в 3 раза быстрее, чем встроенный json при нагрузках
  • simplejson примерно на 30% быстрее, чем встроенный json в дампах

Отказ от ответственности:

Вышеприведенные операторы находятся в python-2.7.3 и simplejson 3.3.0 (с ускорениями c) И чтобы убедиться, что мой ответ также не чувствителен ко времени, вы должны запустить свои собственные тесты , чтобы проверить, так как он сильно варьируется между версиями; нет простого ответа, который не чувствителен ко времени.

Как узнать, включены ли ускорения C в simplejson:

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

ОБНОВЛЕНИЕ: Недавно я столкнулся с библиотекой под названием ujson , которая работает в ~ 3 раза быстрее, чем simplejson с некоторыми базовыми тестами.

21 голосов
/ 29 января 2011

Я тестировал json, simplejson и cjson.

  • самый быстрый cjson
  • simplejson почти наравне с cjson
  • json примерно в 10 раз медленнее, чем 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
9 голосов
/ 18 марта 2016

Некоторые значения по-разному сериализуются между simplejson и json.

Примечательно, что экземпляры collections.namedtuple сериализуются как массивы json, а как объекты simplejson. Вы можете переопределить это поведение, передав namedtuple_as_object=False в simplejson.dump, но по умолчанию поведение не совпадает.

>>> 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]'
7 голосов
/ 14 октября 2013

Я обнаружил несовместимость API с Python 2.7 по сравнению с simplejson 3.3.1 в том, генерирует ли выходные данные объекты str или unicode. например,

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

против

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

Если предпочтение состоит в том, чтобы использовать simplejson, то это можно устранить, принудительно указав строку аргумента в Unicode, например:

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

Принуждение требует знания оригинальной кодировки, например:

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

Это не исправит проблема 40

5 голосов
/ 03 апреля 2009

Еще одна причина, по которой проекты используют simplejson, заключается в том, что встроенный json изначально не включал в себя ускорения C, поэтому разница в производительности была заметной.

5 голосов
/ 03 апреля 2009

Встроенный модуль json включен в Python 2.6. Любые проекты, которые поддерживают версии Python <2.6, должны иметь запасной вариант. Во многих случаях этот резерв составляет <code>simplejson.

4 голосов
/ 03 апреля 2009

Вот (ныне устаревшее) сравнение библиотек jthon Python:

Сравнение модулей JSON для Python ( ссылка на архив )

Независимо от результатов этого сравнения вы должны использовать стандартную библиотеку json, если вы используете Python 2.6. И ... в противном случае можно просто использовать simplejson.

2 голосов
/ 24 июня 2016

В python3, если у вас строка b'bytes', с json вам нужно .decode() содержимое, прежде чем вы сможете его загрузить. simplejson позаботится об этом, так что вы можете просто сделать simplejson.loads(byte_string).

...