【问题标题】:What are the differences between json and simplejson Python modules?json 和 simplejson Python 模块有什么区别?
【发布时间】:2010-10-17 07:14:02
【问题描述】:

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

【问题讨论】:

    标签: python json simplejson


    【解决方案1】:

    内置的 json 模块已包含在 Python 2.6 中。任何支持 Python simplejson。

    【讨论】:

      【解决方案2】:

      jsonissimplejson,添加到标准库中。但是由于json 是在 2.6 中添加的,simplejson 具有处理更多 Python 版本(2.4+)的优势。

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

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

      try:
          import simplejson as json
      except ImportError:
          import json
      

      【讨论】:

      • 现在如果我能让 pyflakes 停止抱怨 redefinition of unused 'json'
      • 它们不一样也不兼容,simplejson有一个JSONDecodeError,json有一个ValueError
      • @BjornTipling JSONDecodeErrorValueError 的子类
      • 假设您拥有最新的 Python,我不同意上述答案。 Python 2.7 中的内置(非常棒!!!)Json 库与 simplejson 一样快,并且拒绝修复的 unicode 错误更少。见答案stackoverflow.com/a/16131316/78234
      • Python2.7 json 似乎采用了 simplejson v2.0.9,这远远落后于当前的 simplejson v3.6.5。有很多值得导入 simplejson 的改进
      【解决方案3】:

      以下是 Python json 库的(现已过时的)比较:

      Comparing JSON modules for Python (archive link)

      无论此比较的结果如何,如果您使用的是 Python 2.6,您都应该使用标准库 json。而且.. 还不如直接使用 simplejson。

      【讨论】:

        【解决方案4】:

        项目使用 simplejson 的另一个原因是内置 json 最初没有包含其 C 加速,因此性能差异很明显。

        【讨论】:

          【解决方案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 呢?

          【讨论】:

            【解决方案6】:

            我一直在对 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
            

            【讨论】:

            • 请为实际测试模块添加一个粘贴。
            • 哪些版本的 Python 和有问题的库?
            • 这不再是真的了。 python2.7中的json是性能提升。
            【解决方案7】:

            我不得不不同意其他答案:内置 json 库(在 Python 2.7 中)不一定比 simplejson 慢。它也没有this annoying unicode bug

            这是一个简单的基准测试:

            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 秒

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

            由于我目前正在构建 Web 服务,所以dumps() 更为重要——并且始终首选使用标准库。

            另外,cjson在过去 4 年没有更新,所以我不会碰它。

            【讨论】:

            • 这是误导。 My answer below 解释了原因。
            • 在我的 Win7 PC (i7 CPU) 上,json (CPython 3.5.0) 在简单|复杂转储上快 68%|45%,在简单|复杂负载上快 35%|17% w.r.t。 simplejson v3.8.0 使用您的基准代码进行 C 加速。因此,我不会再在此设置中使用 simplejson。
            • 我刚刚在 Python 3.6.1 上运行了这个,json 在所有测试中获胜或相同。事实上,json 的速度比现实世界中的复杂数据转储测试快两倍!
            【解决方案8】:

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

            我自己做了一些研究后发现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 倍。

            【讨论】:

            • 感谢您提及 ujson。这个把我带到另一个图书馆RapidJSON,看起来维护得更好
            • 不要使用 ujson,它充满了错误、内存泄漏和崩溃,并且很长一段时间没有更新。我们已经放弃它并切换到 simplejson,因为它比 json 具有更多功能并且已更新
            • @amohr 幸运的是,你的评论没有很好地老化 ;-) ujson 看起来非常活跃和活跃,因为...... 2020 年 3 月:D 所以是的,当你写的时候它是真的,但它似乎(不是仔细观察,因为我对内置 json 很满意)已经变得更好了。
            • 是的,软件相当动态,很高兴有人拿起了火炬!
            【解决方案9】:

            我发现,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)
            

            这是无法修复的issue 40

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案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]'
                

                【讨论】:

                  【解决方案12】:

                  在python3中,如果你是b'bytes'的字符串,json你必须.decode()才能加载内容。 simplejson 会处理这个问题,所以你可以做 simplejson.loads(byte_string)

                  【讨论】:

                  • 在 3.6 版中更改:s 现在可以是字节或字节数组类型。输入编码应为 UTF-8、UTF-16 或 UTF-32。
                  【解决方案13】:

                  json 在最新版本的加载和转储两种情况下似乎都比 simplejson

                  测试版本:

                  • 蟒蛇: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'}}
                  

                  对于版本:

                  • 蟒蛇:3.7.4
                  • json: 2.0.9
                  • simplejson: 3.17.0

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

                  【讨论】:

                    猜你喜欢
                    • 2011-12-18
                    • 2016-04-23
                    • 2011-04-10
                    • 2013-01-11
                    • 2015-11-25
                    • 2011-10-18
                    • 2011-03-01
                    • 2011-06-13
                    相关资源
                    最近更新 更多