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

核能气质少年 提交于 2020-02-27 21:25:42

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


#1楼

我必须不同意其他答案:内置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年中未更新,因此我不会去碰它。


#2楼

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

经过一些我自己的研究,我发现, 如果您将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 speedups),并且为了确保我的回答也不对时间敏感,您应该运行自己的测试以进行检查,因为版本之间的差异很大; 没有时间敏感的简单答案。

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

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

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


#3楼

我发现与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


#4楼

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


#5楼

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?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!