json和simplejson Python模块之间有什么区别?


Answers:


391

json simplejson,已添加到stdlib中。但是自从json2.6中添加以来,它simplejson具有在更多Python版本(2.4+)上工作的优势。

simplejson的更新频率也比Python高,因此,如果您需要(或想要)最新版本simplejson,则尽可能使用它自己。

我认为,一种好的做法是将其中一个作为后备。

try:
    import simplejson as json
except ImportError:
    import json

2
现在,如果我只能让pyflakes停止抱怨redefinition of unused 'json'
James McMahon

5
它们既不相同也不兼容,simplejson具有JSONDecodeError,json具有ValueError
Bjorn

3
@BjornTipling JSONDecodeErrorValueError
elhefe

30
如果您拥有最新的Python,我不同意上述答案。Python 2.7中内置的(很棒的加号!!!)Json库与simplejson一样快,并且具有较少的无法修复的unicode错误。请参阅答案stackoverflow.com/a/16131316/78234
塔尔·魏斯

1
似乎Python2.7 json采用了simplejson v2.0.9,在撰写本文时,它远远落后于当前的simplejson v3.6.5。有很多改进值得导入simplejson
野口健二(Kenji Noguchi)

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,Linux 64位)上的结果:

复杂的现实世界数据:
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速度更快。

由于我当前正在构建Web服务,dumps()因此更为重要-并且始终首选使用标准库。

另外,cjson在过去的4年中没有更新,因此我不会去碰它。


这是误导。我在下面的回答解释了原因。
notbad.jpeg 2015年

2
在我的Win7 PC(i7 CPU)上,使用基准测试代码,在使用C加速的v3.8.0 json上进行简单|复杂转储时,(CPython 3.5.0)的速度提高了68%| 45%,而在简单|复杂负载下的速度提高了35%| 17%simplejson。因此,在此设置中我将不再使用simplejson。
2015年

1
我只是在Python 3.6.1上运行了该命令,并且json在所有测试中获胜还是相同。实际上,json它比复杂的现实世界数据转储测试的速度快两倍!
CpILL

27

所有这些答案都不太有用,因为它们对时间敏感

对我自己进行一些研究后,我发现simplejson如果将其更新为最新版本,确实比内置速度更快。

pip/easy_install我想在ubuntu 12.04上安装2.3.2,但是在发现最新simplejson版本实际上是3.3.0之后,我更新了它并重新进行了时间测试。

  • simplejsonjson负载下的内置速度快3倍
  • simplejsonjson转储时的内置速度快30%

免责声明:

上面的语句在python-2.7.3和simplejson 3.3.0中(使用c speedups),并且要确保我的回答也不是时间敏感的,您应该运行自己的测试以进行检查,因为版本之间的差异很大;没有时间敏感的简单答案。

如何判断是否在simplejson中启用了C加速:

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

更新:我最近遇到了一个名为ujson的库,它比simplejson某些基本测试的执行速度快约3倍。


感谢您提及ujson。这使我进入了另一个库RapidJSON,它看起来维护得更好
MCMZL

“ simplejson 3.3.0(使用C加速)”真的吗?更诚实地说,并在不加速c的情况下进行测试。
Reishin

不要使用ujson,它到处都是bug,内存泄漏和崩溃,并且已经有相当一段时间没有更新了。我们放弃了它,并切换到simplejson,因为它比json具有更多功能并已更新
amohr

21

我一直在对json,simplejson和cjson进行基准测试。

  • cjson最快
  • simplejson与cjson差不多
  • json比simplejson慢10倍

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
请为实际的测试模块添加一个粘贴。
Tal Weiss 2013年

4
哪个版本的Python和相关的lib?
Anentropic

6
这不再是真的。python2.7中的json是性能改进。
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

我发现与Python 2.7和simplejson 3.3.1的API不兼容之处在于输出是生成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



2

simplejson模块仅比json快1.5倍(在我的计算机上,使用simplejson 2.1.1和Python 2.7 x86)。

如果需要,可以尝试进行基准测试:http : //abral.altervista.org/jsonpickle-bench.zip 在我的PC上,simplejson比cPickle更快。我也想知道您的基准!

就像Coady所说的,simplejson和json之间的区别可能是simplejson包含_speedups.c。那么,为什么python开发人员不使用simplejson?


2

在python3,如果你的字符串b'bytes',与json你有.decode()内容,然后才能加载它。 simplejson照顾好这个,所以你可以做simplejson.loads(byte_string)


在版本3.6中更改:s现在可以是bytes或bytearray类型。输入编码应为UTF-8,UTF-16或UTF-32。
Mathieu Longtin

1

json 似乎比 simplejson最新版本的加载和转储

测试版本:

  • 的Python: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'}}

对于版本:

  • 的Python:3.7.4
  • json:2.0.9
  • simplejson:3.17.0

json在转储操作期间比simplejson快,但在加载操作期间两者保持相同的速度


0

我在寻找要为Python 2.6安装simplejson时遇到了这个问题。我需要使用json.load()的'object_pairs_hook'来将json文件加载为OrderedDict。熟悉最新版本的Python时,我没有意识到Python 2.6的json模块不包含'object_pairs_hook',因此我为此目的必须安装simplejson。从个人经验来看,这就是为什么我使用simplejson而不是标准json模块的原因。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.