Я видел много проектов, используя simplejson
модуль вместо json
из стандартной библиотеки. Кроме того, существует множество различных модулей simplejson
. Зачем использовать эти альтернативы, а не одну в стандартной библиотеке?
В чем разница между модулями json и simplejson Python?
Ответ 1
json
simplejson
, добавлен в stdlib. Но поскольку json
был добавлен в 2.6, simplejson
имеет преимущество в работе над более версиями Python (2.4+).
simplejson
также обновляется чаще, чем Python, поэтому, если вам нужна (или нужна) последняя версия, лучше всего использовать simplejson
, если это возможно.
Хорошей практикой, на мой взгляд, является использование того или другого в качестве резерва.
try: import simplejson as json
except ImportError: import json
Ответ 2
Я не согласен с другими ответами: встроенная библиотека json
(в Python 2.7) не обязательно медленнее, чем simplejson
. У этого также нет эта неприятная ошибка unicode.
Вот простой тест:
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 dumps 1.56666707993 секунды
simplejson dumps 2.25638604164 секунды
json load 2.71256899834 секунды
simplejson load 1.29233884811 секундПростые данные:
json dumps 0.370109081268 секунд
спейсы простого пользователя 0.574181079865 секунды
json load 0.422876119614 секунды
simplejson load 0.270955085754 секунды
Для сброса, json
быстрее, чем simplejson
.
Для загрузки simplejson
выполняется быстрее.
Поскольку в настоящее время я создаю веб-службу, dumps()
более важен, и использование стандартной библиотеки всегда предпочтительнее.
Кроме того, cjson
не обновлялся за последние 4 года, поэтому я бы не стал его трогать.
Ответ 3
Все эти ответы не очень полезны, потому что они чувствительны к времени.
После самостоятельного исследования я обнаружил, что simplejson
действительно быстрее, чем встроенный, if, который вы обновляете до последней версии.
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))
UPDATE: Недавно я встретил библиотеку под названием ujson, которая выполняет ~ 3 раза быстрее, чем simplejson
с некоторыми базовыми тестами.
Ответ 4
Я сравнивал json, simplejson и cjson.
- cjson самый быстрый
- simplejson почти на одном уровне с cjson
- json примерно в 10 раз медленнее, чем simplejson
$ 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
Ответ 5
Несовместимость API, которую я обнаружил, с Python 2.7 vs 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
Ответ 6
Встроенный модуль json
включен в Python 2.6. Любые проекты, поддерживающие версии Python < 2.6 необходимо иметь резервную копию. Во многих случаях этот резерв равен simplejson
.
Ответ 7
Еще одна причина, по которой проекты используют simplejson, заключается в том, что встроенный json первоначально не включал свои ускорители C, поэтому разница в производительности была заметна.
Ответ 8
Здесь (теперь устаревшее) сравнение библиотек Python json:
Сравнение модулей JSON для Python (ссылка на архив)
Независимо от результатов этого сравнения, вы должны использовать стандартную библиотеку json, если вы находитесь на Python 2.6. И.. может также просто использовать simplejson в противном случае.
Ответ 9
модуль simplejson просто в 1,5 раза быстрее, чем json (на моем компьютере, с simplejson 2.1.1 и Python 2.7 x86).
Если вы хотите, вы можете попробовать тест: http://abral.altervista.org/jsonpickle-bench.zip На моем компьютере simplejson быстрее, чем cPickle. Я также хотел бы узнать ваши тесты!
Возможно, как сказал Coady, разница между simplejson и json заключается в том, что simplejson включает _speedups.c. Итак, почему разработчики python не используют simplejson?
Ответ 10
Некоторые значения сериализуются по-разному между 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]'
Ответ 11
Я столкнулся с этим вопросом, поскольку я искал установку simplejson для Python 2.6. Мне нужно было использовать "object_pairs_hook" для json.load(), чтобы загрузить json файл в качестве OrderedDict. Будучи знакомым с более поздними версиями Python, я не понимал, что модуль json для Python 2.6 не включает "object_pairs_hook", поэтому мне пришлось установить simplejson для этой цели. Из личного опыта именно поэтому я использую simplejson в отличие от стандартного модуля json.
Ответ 12
В python3, если у вас есть строка b'bytes'
, с json
вам нужно .decode()
содержимое, прежде чем вы сможете загрузить его. simplejson
позаботится об этом, поэтому вы можете просто сделать simplejson.loads(byte_string)
.