jsonとsimplejson Pythonモジュールの違いは何ですか?


381

標準ライブラリのsimplejsonモジュールの代わりにjsonモジュールを使用する多くのプロジェクトを見てきました。また、多くの異なるsimplejsonモジュールがあります。標準ライブラリの代わりにこれらの代替を使用するのはなぜですか?

回答:


391

json simplejson、stdlibに追加されます。しかしjsonは2.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
Tal Weiss

1
Python2.7 jsonはsimplejson v2.0.9を採用しているようですが、これは現在のsimplejson v3.6.5の執筆時点ではかなり遅れています。インポートsimplejsonに値する多くの改善があります
野口健司

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)では、json(CPython 3.5.0)はsimplejson、ベンチマークコードを使用したCスピードアップで、単純|複雑なダンプで68%| 45%高速で、単純|複雑なロードで35%| 17%wrt v3.8.0です。したがって、この設定ではsimplejsonを使用しません。
mab 2015年

1
私はこれをPython 3.6.1で実行しただけでjson、すべてのテストで勝ちました。実際json、複雑な実世界のデータダンプテストの2倍弱の速さです。
CpILL

27

これらの回答はすべて、時間に敏感であるため、あまり役に立ちません。

私自身、私のいくつかの研究を行った後、それが見つけsimplejson、速く組み込みよりも確かにある場合、あなたはそれが最新のバージョンに更新を維持。

pip/easy_installubuntu 12.04に2.3.2をインストールしたかったのですが、最新simplejsonバージョンが実際には3.3.0であることを確認した後、それを更新して時間テストを再実行しました。

  • simplejsonjsonロード時のビルトインより約3倍速い
  • simplejsonjsonダンプでの組み込みよりも約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))

更新:私は最近、いくつかの基本的なテストよりも〜3倍高速に実行されているujsonというライブラリに出会いましsimplejson


ujsonについて言及していただきありがとうございます。これは私をより良く維持されているように見える別のライブラリRapidJSONに導きました
MCMZL 2018

「simplejson 3.3.0(cスピードアップあり)」本当に?より正直になり、Cスピードアップなしでテストします。
Reishin

ujsonは使用しないでください。バグやメモリリーク、クラッシュが散らばっていて、しばらく更新されていません。我々はそれを捨て、それはJSONより多くの機能を持っており、更新されるとのsimplejsonに切り替えた
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

4
問題のPythonとlibsのバージョンは?
エントロピー

6
これはもう本当ではありません。python2.7のjsonはパフォーマンスの改善です。
zengr 2013

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

私が見つけたAPIの非互換性は、Python 2.7とsimplejson 3.3.1で、出力が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を使用するもう1つの理由は、組み込みの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の型をバイトまたはバイト配列にすることができます。入力エンコーディングは、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ファイルをOrderedDictとしてロードするには、json.load()の「object_pairs_hook」を使用する必要がありました。最近のバージョンのPythonに慣れているので、Python 2.6のjsonモジュールに「object_pairs_hook」が含まれていないことに気づかなかったため、この目的のためにsimplejsonをインストールする必要がありました。個人的な経験から、これが標準のjsonモジュールではなくsimplejsonを使用する理由です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.