我见过许多项目使用simplejson
模块而不是json
标准库中的模块。此外,还有许多不同的simplejson
模块。为什么要使用这些替代方案,而不是标准库中的替代方案?
13 回答
json
是 simplejson
,添加到标准库。但是自从json
在 2.6 中添加以来,simplejson
它的优势在于可以处理更多的 Python 版本(2.4+)。
simplejson
也比 Python 更频繁地更新,所以如果你需要(或想要)最新版本,最好尽可能使用simplejson
它自己。
在我看来,一个好的做法是使用一个或另一个作为后备。
try:
import simplejson as json
except ImportError:
import json
我不得不不同意其他答案:内置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年没有更新,所以我不会碰它。
所有这些答案都不是很有帮助,因为它们是时间敏感的。
经过我自己的一些研究后,我发现它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 倍。
我一直在对 json、simplejson 和 cjson 进行基准测试。
- cjson最快
- simplejson 和 cjson 差不多
- json 比 simplejson 慢大约 10 倍
$ 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]'
我发现,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
项目使用 simplejson 的另一个原因是内置 json 最初没有包含其 C 加速,因此性能差异很明显。
内置json
模块包含在 Python 2.6 中。任何支持 Python < 2.6 版本的项目都需要有一个回退。在许多情况下,回退是simplejson
.
这是 Python json 库的(现已过时的)比较:
无论此比较的结果如何,如果您使用的是 Python 2.6,您都应该使用标准库 json。而且.. 还不如只使用 simplejson 。
json
似乎比simplejson
最新版本的加载和转储都快
测试版本:
- 蟒蛇:3.6.8
- json: 2.0.9
- 简单的json: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
- 简单的json:3.17.0
json 在转储操作期间比 simplejson 快,但在加载操作期间都保持相同的速度
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 呢?
在python3中,如果你是一个字符串b'bytes'
,json
你必须.decode()
在加载它之前使用内容。 simplejson
照顾这个,所以你可以做simplejson.loads(byte_string)
。
我在为 Python 2.6 安装 simplejson 时遇到了这个问题。我需要使用 json.load() 的“object_pairs_hook”来将 json 文件加载为 OrderedDict。熟悉 Python 的更新版本后,我没有意识到 Python 2.6 的 json 模块不包含“object_pairs_hook”,因此我必须为此安装 simplejson。从个人经验来看,这就是我使用 simplejson 而不是标准 json 模块的原因。