Я видел много проектов, использующих simplejson
модуль вместо json
модуля из стандартной библиотеки. Также есть много разных simplejson
модулей. Зачем использовать эти альтернативы, вместо того, что в стандартной библиотеке?
Я видел много проектов, использующих simplejson
модуль вместо json
модуля из стандартной библиотеки. Также есть много разных simplejson
модулей. Зачем использовать эти альтернативы, вместо того, что в стандартной библиотеке?
Ответы:
json
есть simplejson
, добавлено в stdlib. Но поскольку он json
был добавлен в simplejson
версии 2.6, он имеет преимущество работы с несколькими версиями Python (2.4+).
simplejson
также обновляется чаще, чем Python, поэтому, если вам нужна (или вы хотите) последняя версия, лучше использовать ее simplejson
, если это возможно.
На мой взгляд, хорошей практикой является использование одного или другого в качестве запасного варианта.
try:
import simplejson as json
except ImportError:
import json
JSONDecodeError
является подклассомValueError
Я должен не согласиться с другими ответами: встроенная 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 dumps 0.370109081268 секунд
simplejson dumps 0.574181079865 секунд
json load 0.422876119614 секунд
simplejson загрузок 0.270955085754 секунд
Для сброса, json
быстрее, чем simplejson
. Для загрузки, simplejson
быстрее.
Поскольку в настоящее время я занимаюсь созданием веб-службы, dumps()
это важнее, и всегда предпочтительнее использовать стандартную библиотеку.
Кроме того, cjson
не обновлялся в течение последних 4 лет, поэтому я бы не стал его трогать.
json
(CPython 3.5.0) на 68% | 45% быстрее на простых | сложных дампах и на 35% | 17% на простых | сложных нагрузках по simplejson
сравнению с v3.8.0 с ускорением C с использованием кода вашего теста. Поэтому я бы больше не использовал simplejson с этой настройкой.
json
выиграл или то же самое для всех тестов. На самом деле json
это чуть меньше, чем вдвое быстрее, чем сложный тест на создание реальных дампов данных!
Все эти ответы не очень полезны, потому что они чувствительны ко времени .
Проведя собственное исследование, я обнаружил, что 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). Чтобы убедиться, что мой ответ также не чувствителен ко времени, вы должны запустить свои собственные тесты, чтобы проверить, так как он сильно варьируется между версиями; нет простого ответа, который не чувствителен ко времени.
import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, '_speedups', False))
ОБНОВЛЕНИЕ: я недавно столкнулся с библиотекой под названием ujson, которая работает в ~ 3 раза быстрее, чем simplejson
с некоторыми базовыми тестами.
Я тестировал json, simplejson и cjson.
$ 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
Некоторые значения по-разному сериализуются между 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]'
Я обнаружил, что несовместимость 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
Вот (ныне устаревшее) сравнение библиотек Python json:
Сравнение модулей JSON для Python ( ссылка на архив )
Независимо от результатов этого сравнения вы должны использовать стандартную библиотеку json, если вы используете Python 2.6. И ... в противном случае можно просто использовать simplejson.
Модуль 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?
В python3, если у вас есть строка b'bytes'
, json
вы должны .decode()
загрузить содержимое, прежде чем сможете его загрузить. simplejson
заботится об этом, так что вы можете просто сделать simplejson.loads(byte_string)
.
json
кажется быстрее, чем simplejson
в обоих случаях загрузки и выгрузки в последней версии
Протестированные версии:
Результаты:
>>> def test(obj, call, data, times):
... s = datetime.now()
... print("calling: ", call, " in ", obj, " ", times, " times")
... for _ in range(times):
... r = getattr(obj, call)(data)
... e = datetime.now()
... print("total time: ", str(e-s))
... return r
>>> test(json, "dumps", data, 10000)
calling: dumps in <module 'json' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\json\\__init__.py'> 10000 times
total time: 0:00:00.054857
>>> test(simplejson, "dumps", data, 10000)
calling: dumps in <module 'simplejson' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\simplejson\\__init__.py'> 10000 times
total time: 0:00:00.419895
'{"1": 100, "2": "acs", "3.5": 3.5567, "d": [1, "23"], "e": {"a": "A"}}'
>>> test(json, "loads", strdata, 1000)
calling: loads in <module 'json' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\json\\__init__.py'> 1000 times
total time: 0:00:00.004985
{'1': 100, '2': 'acs', '3.5': 3.5567, 'd': [1, '23'], 'e': {'a': 'A'}}
>>> test(simplejson, "loads", strdata, 1000)
calling: loads in <module 'simplejson' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\simplejson\\__init__.py'> 1000 times
total time: 0:00:00.040890
{'1': 100, '2': 'acs', '3.5': 3.5567, 'd': [1, '23'], 'e': {'a': 'A'}}
Для версий:
json был быстрее, чем simplejson при работе с дампами, но оба поддерживали одинаковую скорость при работе с нагрузками
Я столкнулся с этим вопросом, когда искал возможность установить simplejson для Python 2.6. Мне нужно было использовать 'object_pairs_hook' из json.load (), чтобы загрузить файл json как OrderedDict. Будучи знаком с более поздними версиями Python, я не осознавал, что модуль json для Python 2.6 не содержит 'object_pairs_hook', поэтому мне пришлось установить simplejson для этой цели. Исходя из личного опыта, именно поэтому я использую simplejson, а не стандартный модуль json.
redefinition of unused 'json'