it-swarm.com.ru

Каковы различия между модулями json и simplejson Python?

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

363
Lakshman Prasad

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

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

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

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

Я должен не согласиться с другими ответами: встроенная 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 сбрасывает 1,56666707993 секунд
simplejson сбрасывает 2,25638604164 секунд
JSON загружает 2,71256899834 секунд
simplejson загружает 1,29233884811 секунд

Простые данные:
JSON сбрасывает 0,370109081268 секунд
simplejson сбрасывает 0,574181079865 секунд
JSON загружает 0,422876119614 секунд
simplejson загружает 0,270955085754 секунд

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

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

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

80
Tal Weiss

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

Проведя свое собственное исследование, я обнаружил, что 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))

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

24
notbad.jpeg

Я тестировал 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
21
Chris

Некоторые значения по-разному сериализуются между 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]'
9
pfhayes

Я обнаружил несовместимость 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)

Это не исправит выпуск 4

7
jjc

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

5
thedz

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

5
A. Coady

Вот (теперь уже устаревшее) сравнение библиотек Python json:

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

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

4
Van Gale

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

2
voidnologo

модуль simplejson просто в 1,5 раза быстрее, чем json (на моем компьютере с simplejson 2.1.1 и Python 2.7 x86).

Если вы хотите, вы можете попробовать тест: http://abral.altervista.org/jsonpickle-bench.Zip На моем ПК simplejson работает быстрее, чем cPickle. Я хотел бы знать также ваши ориентиры!

Вероятно, как сказал Коуди, разница между simplejson и json заключается в том, что simplejson включает _speedups.c. Итак, почему python разработчики не используют simplejson?

2
Jeko

Я столкнулся с этим вопросом, когда искал установку simplejson для Python 2.6. Мне нужно было использовать 'object_pairs_hook' из json.load (), чтобы загрузить файл json как OrderedDict. Будучи знакомым с более свежими версиями Python, я не осознавал, что модуль json для Python 2.6 не содержит 'object_pairs_hook', поэтому мне пришлось установить simplejson для этой цели. Исходя из личного опыта, именно поэтому я использую simplejson, а не стандартный модуль json.

0
BeeLabeille