Які відмінності між модулями json та simplejson Python?


381

Я бачив багато проектів, що використовують simplejsonмодуль замість jsonмодуля зі стандартної бібліотеки. Також існує багато різних simplejsonмодулів. Навіщо використовувати ці альтернативи замість тієї, що знаходиться в Стандартній бібліотеці?

Відповіді:


391

json є simplejson , додається до stdlib. Але оскільки він jsonбув доданий в 2.6, simplejsonмає перевагу працювати над більшою версією Python (2.4+).

simplejsonтакож оновлюється частіше, ніж Python, тому якщо вам потрібна (або потрібна) остання версія, найкраще скористатися simplejsonсамою, якщо це можливо.

Доброю практикою, на мою думку, є використання того чи іншого як резервного.

try:
    import simplejson as json
except ImportError:
    import json

2
Тепер, якщо мені вдалося отримати лише піфляки, щоб перестати скаржитисяredefinition of unused 'json'
Джеймс Макмахон,

5
Вони не однакові і не сумісні, у simplejson є JSONDecodeError, а у json - ValueError
Bjorn

3
@BjornTipling JSONDecodeErrorє підкласомValueError
elhefe

30
Я не згоден з вищезазначеною відповіддю, припускаючи, що у вас є актуальний Python. Вбудована (великий плюс !!!) бібліотека Json в Python 2.7 настільки ж швидка, як simplejson, і має менше відмовлених у виправленні помилок unicode. Дивіться відповідь stackoverflow.com/a/16131316/78234
Tal Weiss

1
Здається, Python2.7 json прийняв simplejson v2.0.9, що значно відстає від поточного simplejson v3.6.5 на час написання. Є багато вдосконалень, які вартують імпорту simplejson
Kenji

82

Я не погоджуюся з іншими відповідями: вбудована 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, 64-бітний Linux):

Складні дані в реальному світі:
скидання json 1,56666707993 секунд
симплейнсон скидає 2,225638604164 секунд
json навантажує 2,71256899834 секунд
симплейсон завантажує 1,229233884811 секунд

Прості дані:
скидання json 0,370109081268 секунд
simplejson скидає 0,574181079865 секунд
json завантажує 0,422876119614 секунд
simplejson завантажує 0,270955085754 секунди

Для демпінгу jsonшвидше, ніж simplejson. Для завантаження simplejsonшвидше.

Оскільки я зараз будую веб-сервіс, dumps()важливіше - і використання стандартної бібліотеки завжди є кращим.

Крім того, cjsonне оновлювався протягом останніх 4 років, тому я б не торкався цього.


Це вводить в оману. Моя відповідь нижче пояснює, чому.
notbad.jpeg

2
На моєму ПК Win7 (i7 CPU), json(CPython 3.5.0) на 68% | 45% швидше на простих | складних скидах і 35% | 17% на простих | складних навантаженнях wrt simplejsonv3.8.0 із скороченням С, використовуючи свій контрольний код. Тому я більше не використовую simplejson з цією установкою.
мак

1
Я просто запустив це на Python 3.6.1 і jsonвиграв або є однаковим для всіх тестів. Насправді jsonтрохи менше, ніж удвічі швидше, ніж складний тест звалищ даних у реальному світі!
CpILL

27

Усі ці відповіді не дуже корисні, оскільки залежать від часу .

Провівши кілька власних досліджень, я виявив, що 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деякі основні тести.


Дякуємо, що згадали про ujson. Це привело мене до іншої бібліотеки RapidJSON, яка виглядає доглянутішою
MCMZL

"simplejson 3.3.0 (з c прискореннями)" о, справді? бути більш чесним і протестувати його без c прискорень.
Решин

не використовуйте ujson, він засмічений помилками та витоками пам’яті та збоями, і він не оновлювався вже досить давно. Ми кинули його і перейшли на simplejson як він має більше функціональних можливостей, ніж JSON і оновлюється
amohr

21

Я проводив порівняльний аналіз 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

6
Будь ласка, додайте пасти для фактичного тестового модуля.
Тал Вайс

4
які версії Python та ліктів, про які йдеться?
Анентропний

6
Це вже не відповідає дійсності. json в python2.7 - це покращення продуктивності.
zengr

11

Деякі значення серіалізуються по-різному між 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

Я виявив несумісність 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


6

Ще однією причиною використання проектів simplejson є те, що вбудований json спочатку не включав його C-прискорення, тому різниця в продуктивності була помітна.


5

Вбудований jsonмодуль включений у Python 2.6. Будь-які проекти, що підтримують версії Python <2.6, повинні мати резервну копію. У багатьох випадках ця резервна ситуація є simplejson.


4

Ось (застаріле) порівняння бібліотек Python json:

Порівняння модулів JSON для Python ( архів посилання )

Незалежно від результатів у цьому порівнянні, ви повинні використовувати стандартну бібліотеку json, якщо ви перебуваєте на Python 2.6. І .. можливо, просто використовувати simplejson в іншому випадку.


2

модуль 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

У python3, якщо ви є рядком b'bytes', jsonви маєте .decode()вміст, перш ніж ви зможете його завантажити. simplejsonподбає про це, щоб ви могли просто зробити simplejson.loads(byte_string).


Змінено у версії 3.6: s тепер може бути тип байтів або байт-масив. Кодування входу має бути UTF-8, UTF-16 або UTF-32.
Матьє Лонгтін

1

json здається швидше, ніж simplejson в обох випадках завантаження та скидання в останній версії

Тестовані версії:

  • пітон: 3.6.8
  • json: 2.0.9
  • simplejson: 3.16.0

Результати:

>>> 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'}}

Для версій:

  • пітон: 3.7.4
  • json: 2.0.9
  • simplejson: 3.17.0

json був швидшим, ніж simplejson під час роботи звалищ, але обидва підтримували однакову швидкість під час навантажень


0

Я натрапив на це питання, коли шукав встановити simplejson для Python 2.6. Мені потрібно було використовувати 'object_pairs_hook' з json.load (), щоб завантажити файл json як OrdersDict. Ознайомившись з більш новими версіями Python, я не зрозумів, що модуль json для Python 2.6 не містить 'object_pairs_hook', тому для цього мені довелося встановити simplejson. З особистого досвіду, саме тому я використовую simplejson на відміну від стандартного модуля json.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.