Sự khác biệt giữa các mô-đun Python json và Simplejson là gì?


381

Tôi đã thấy nhiều dự án sử dụng simplejsonmô-đun thay vì jsonmô-đun từ Thư viện tiêu chuẩn. Ngoài ra, có nhiều simplejsonmô-đun khác nhau . Tại sao sẽ sử dụng các lựa chọn thay thế này, thay vì một trong Thư viện tiêu chuẩn?

Câu trả lời:


391

json simplejson , được thêm vào stdlib. Nhưng kể từ khi jsonđược thêm vào 2.6, simplejsoncó lợi thế là làm việc trên nhiều phiên bản Python hơn (2.4+).

simplejsoncũng được cập nhật thường xuyên hơn Python, vì vậy nếu bạn cần (hoặc muốn) phiên bản mới nhất, tốt nhất nên sử dụng simplejsonchính nó, nếu có thể.

Theo tôi, một cách thực hành tốt là sử dụng cái này hay cái kia làm dự phòng.

try:
    import simplejson as json
except ImportError:
    import json

2
Bây giờ nếu tôi chỉ có thể khiến những chiếc bánh quy ngừng phàn nàn vềredefinition of unused 'json'
James McMahon

5
Chúng không giống nhau và cũng không tương thích, Simplejson có JSONDecodeError và json có ValueError
Bjorn

3
@BjornTipling JSONDecodeErrorlà một lớp con củaValueError
elhefe

30
Tôi không đồng ý với câu trả lời ở trên giả sử bạn có một Python cập nhật. Thư viện Json tích hợp (cộng lớn !!!) trong Python 2.7 nhanh như Simplejson và có ít lỗi unicode không được sửa chữa. Xem câu trả lời stackoverflow.com/a/16131316/78234
Tal Weiss

1
Có vẻ như Python2.7 json đã áp dụng Simplejson v2.0.9, thua xa so với Simplejson v3.6.5 hiện tại khi viết. Có rất nhiều cải tiến đáng để nhập đơn giản
Kenji Noguchi

82

Tôi phải không đồng ý với các câu trả lời khác: jsonthư viện tích hợp (trong Python 2.7) không nhất thiết phải chậm hơn simplejson. Nó cũng không có lỗi unicode gây phiền nhiễu này .

Đây là một điểm chuẩn đơn giản:

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)

Và kết quả trên hệ thống của tôi (Python 2.7.4, Linux 64-bit):

Dữ liệu trong thế giới thực phức tạp:
json đổ 1.56666707993 giây
Simplejson bãi 2.25638604164 giây
json tải 2.71256899834 giây
Simplejson tải 1.29233884811 giây

Dữ liệu đơn giản:
json đổ 0,370109081268 giây
Simplejson kết xuất 0,574181079865 giây
json tải 0.422876119614 giây
Simplejson tải 0.270955085754 giây

Đối với bán phá giá, jsonlà nhanh hơn simplejson. Để tải, simplejsonlà nhanh hơn.

Vì tôi hiện đang xây dựng một dịch vụ web, dumps()điều quan trọng hơn là sử dụng thư viện chuẩn và luôn được ưu tiên.

Ngoài ra, cjsonđã không được cập nhật trong 4 năm qua, vì vậy tôi sẽ không chạm vào nó.


Điều này là sai lệch. Câu trả lời của tôi dưới đây giải thích tại sao.
notbad.jpeg

2
Trên PC Win7 của tôi (CPU i7), json(CPython 3.5.0) nhanh hơn 68% | 45% đối với các bãi đơn giản | phức tạp và 35% | 17% đối với đơn giản | tải phức tạp wrt simplejsonv3.8.0 với tốc độ C sử dụng mã điểm chuẩn của bạn. Do đó, tôi sẽ không sử dụng Simplejson nữa với thiết lập này.
mab

1
Tôi chỉ chạy cái này trên Python 3.6.1 và jsonthắng hoặc giống nhau cho tất cả các bài kiểm tra. Trong thực tế jsonlà nhanh hơn một chút so với thử nghiệm bãi bỏ dữ liệu trong thế giới thực phức tạp!
CpILL

27

Tất cả những câu trả lời này không hữu ích lắm vì chúng nhạy cảm với thời gian .

Sau khi thực hiện một số nghiên cứu của riêng tôi, tôi thấy rằng simplejsonnó thực sự nhanh hơn bản dựng, nếu bạn giữ nó cập nhật lên phiên bản mới nhất.

pip/easy_installmuốn cài đặt 2.3.2 trên Ubuntu 12.04, nhưng sau khi tìm ra simplejsonphiên bản mới nhất thực sự là 3.3.0, vì vậy tôi đã cập nhật nó và chạy lại các bài kiểm tra thời gian.

  • simplejsonnhanh hơn khoảng 3 lần so với nội dung jsontải
  • simplejsonnhanh hơn khoảng 30% so với tích hợp jsontại các bãi

Tuyên bố từ chối trách nhiệm:

Các câu trên nằm trong python-2.7.3 và Simplejson 3.3.0 (với c speedups) Và để đảm bảo câu trả lời của tôi cũng không nhạy cảm với thời gian, bạn nên chạy thử nghiệm của riêng mình để kiểm tra vì nó thay đổi rất nhiều giữa các phiên bản; không có câu trả lời dễ dàng mà không nhạy cảm với thời gian.

Làm thế nào để biết nếu tăng tốc độ C được bật trong Simplejson:

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

CẬP NHẬT: Gần đây tôi tình cờ thấy một thư viện có tên ujson đang hoạt động nhanh hơn ~ 3 lần so simplejsonvới một số bài kiểm tra cơ bản.


Cảm ơn đã đề cập đến ujson. Điều này dẫn tôi đến một thư viện khác RapidJSON có vẻ được duy trì tốt hơn
MCMZL

"Simplejson 3.3.0 (với c tăng tốc)" oh thật sao? hãy trung thực hơn và kiểm tra nó mà không cần tăng tốc c.
Reishin

không sử dụng ujson, nó chứa đầy lỗi và rò rỉ bộ nhớ và các lỗi và không được cập nhật trong một thời gian. Chúng tôi đã bỏ nó và chuyển sang Simplejson vì nó có nhiều chức năng hơn json và được cập nhật
amohr

21

Tôi đã được điểm chuẩn json, Simplejson và cjson.

  • cjson là nhanh nhất
  • Simplejson gần như ngang bằng với cjson
  • json chậm hơn khoảng 10 lần so với 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
Vui lòng thêm một pastie cho các mô-đun thử nghiệm thực tế.
Tal Weiss

4
phiên bản nào của Python và libs trong câu hỏi?
Anentropic

6
Điều này không còn đúng nữa. json trong python2.7 là cải tiến hiệu suất.
zengr

11

Một số giá trị được tuần tự hóa khác nhau giữa Simplejson và json.

Đáng chú ý, các trường hợp collections.namedtupleđược tuần tự hóa dưới dạng mảng bởi jsonnhưng là đối tượng của simplejson. Bạn có thể ghi đè hành vi này bằng cách chuyển namedtuple_as_object=Falseđến simplejson.dump, nhưng theo mặc định, các hành vi không khớp.

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

Một khả năng không tương thích API mà tôi tìm thấy, với Python 2.7 so với Simplejson 3.3.1 nằm ở việc liệu đầu ra có tạo ra các đối tượng str hay unicode hay không. ví dụ

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

đấu với

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

Nếu ưu tiên là sử dụng Simplejson, thì điều này có thể được giải quyết bằng cách ép chuỗi đối số thành unicode, như trong:

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

Việc ép buộc đòi hỏi phải biết bộ ký tự gốc, ví dụ:

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

Đây không phải là vấn đề sửa chữa 40


6

Một lý do khác khiến các dự án sử dụng Simplejson là json dựng sẵn ban đầu không bao gồm các bộ tăng tốc C của nó, vì vậy sự khác biệt về hiệu suất là đáng chú ý.


5

jsonMô-đun dựng sẵn có trong Python 2.6. Bất kỳ dự án nào hỗ trợ các phiên bản Python <2.6 cần phải có dự phòng. Trong nhiều trường hợp, dự phòng đó là simplejson.



2

mô-đun Simplejson đơn giản là nhanh hơn 1,5 lần so với json (Trên máy tính của tôi, với Simplejson 2.1.1 và Python 2.7 x86).

Nếu bạn muốn, bạn có thể thử điểm chuẩn: http://abral.altervista.org/jsonpickle-bench.zip Trên PC của tôi, Simplejson nhanh hơn cPickle. Tôi cũng muốn biết điểm chuẩn của bạn!

Có lẽ, như Coady đã nói, sự khác biệt giữa Simplejson và json là Simplejson bao gồm _speedups.c. Vì vậy, tại sao các nhà phát triển python không sử dụng Simplejson?


2

Trong python3, nếu bạn là một chuỗi b'bytes', với jsonbạn phải .decode()nội dung trước khi bạn có thể tải nó. simplejsonchăm sóc này vì vậy bạn chỉ có thể làm được simplejson.loads(byte_string).


Đã thay đổi trong phiên bản 3.6: s bây giờ có thể là kiểu byte hoặc bytearray. Mã hóa đầu vào phải là UTF-8, UTF-16 hoặc UTF-32.
Mathieu Longtin

1

json có vẻ nhanh hơn simplejson trong cả hai trường hợp tải và đổ trong phiên bản mới nhất

Phiên bản thử nghiệm:

  • trăn: 3.6.8
  • json: 2.0.9
  • đơn giản: 3.16.0

Các kết quả:

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

Đối với phiên bản:

  • trăn: 3.7.4
  • json: 2.0.9
  • đơn giản: 3.17.0

json nhanh hơn Simplejson trong quá trình vận hành bãi rác nhưng cả hai đều duy trì tốc độ như nhau trong các hoạt động tải


0

Tôi đã gặp câu hỏi này khi tôi đang tìm cách cài đặt Simplejson cho Python 2.6. Tôi cần sử dụng 'object_pairs_hook' của json.load () để tải tệp json dưới dạng OrderedDict. Làm quen với các phiên bản gần đây hơn của Python Tôi không nhận ra rằng mô-đun json cho Python 2.6 không bao gồm 'object_pairs_hook' nên tôi phải cài đặt Simplejson cho mục đích này. Từ kinh nghiệm cá nhân, đây là lý do tại sao tôi sử dụng Simplejson trái ngược với mô-đun json tiêu chuẩn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.