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

我已经看到许多项目使用simplejson模块而不是标准库中的json模块。此外,还有许多不同的simplejson模块。为什么要使用这些替代品,而不是标准库中的替代品?

146084 次浏览

内置的json模块包含在Python 2.6中。任何支持Python <版本的项目;我需要一个退路。在许多情况下,该回退是simplejson

json simplejson,添加到stdlib。但由于json是在2.6中添加的,因此simplejson具有在更多Python版本(2.4+)上工作的优势。

simplejson的更新频率也高于Python,所以如果你需要(或想要)最新版本,最好使用simplejson本身,如果可能的话。

在我看来,一个好的做法是使用其中一种作为后备。

try:
import simplejson as json
except ImportError:
import json

下面是Python json库的比较(现在已经过时了):

比较Python的JSON模块 (归档链接)

不管这个比较的结果如何,如果你使用的是Python 2.6,你应该使用标准库json。和. .否则还不如直接使用simplejson。

项目使用simplejson的另一个原因是内置json最初不包括它的C加速,所以性能差异是显而易见的。

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

如果你愿意,你可以试试基准测试:http://abral.altervista.org/jsonpickle-bench.zip 在我的电脑上,simplejson比cPickle快。我也想知道你的基准!< / p > 可能,正如Coady所说,simplejson和json之间的区别在于simplejson包含_speedps .c。 那么,为什么python开发者不使用simplejson呢?< / p >

我一直在测试json, simplejson和cjson。

  • json是最快的
  • 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

我不得不不同意其他答案:内置的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秒

< br > < p >简单的数据: Json转储0.370109081268秒
Simplejson转储0.574181079865秒
Json加载0.422876119614秒
Simplejson加载0.270955085754秒

对于转储,jsonsimplejson快。 对于加载,simplejson更快

由于我目前正在构建一个web服务,dumps()更重要——使用标准库总是首选。

而且,cjson在过去的4年里没有更新,所以我不会碰它。

所有这些答案都不是很有用,因为它们是时间敏感的

在我自己做了一些研究后,我发现simplejson确实比内置的更快,如果你保持它更新到最新版本。

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

  • 在加载时,simplejson比内置的json快大约3倍
  • simplejson在转储时比内置的json快30%左右

免责声明:

以上语句在python-2.7.3和simplejson 3.3.0中(带有c加速) 为了确保我的答案也不是时间敏感的,你应该运行您自己的测试来检查,因为它在版本之间变化很大;

.

.

.

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

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

我最近遇到了一个名为ujson的库,它通过一些基本的测试比simplejson执行快~3倍。

我发现Python 2.7 vs simplejson 3.3.1的API不兼容在于输出是否产生str或unicode对象。 例如< / p >
>>> from json import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{u'a': u'b'}

vs

>>> 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 2.6安装simplejson时遇到了这个问题。我需要使用json.load()的'object_pairs_hook',以便将json文件加载为OrderedDict。由于熟悉Python的最新版本,我没有意识到Python 2.6的json模块不包括'object_pairs_hook',所以我不得不为此安装simplejson。从个人经验来看,这就是为什么我使用simplejson而不是标准json模块。

一些值在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]'

在python3中,如果你有一个b'bytes'的字符串,使用json,你必须在加载它之前.decode()内容。simplejson处理这个问题,所以你可以只做simplejson.loads(byte_string)

在最新版本中,无论是加载还是转储,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快,但在加载操作中两者保持相同的速度