標準ライブラリのsimplejson
モジュールの代わりにjson
モジュールを使用する多くのプロジェクトを見てきました。また、さまざまなsimplejson
モジュールがあります。標準ライブラリの代わりにこれらの選択肢を使用するのはなぜですか?
json
issimplejson
、stdlibに追加されました。ただし、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
は実際に組み込みよりも高速であることがわかりました。if最新バージョンに更新してください。
pip/easy_install
は2.3.2をubuntu 12.04にインストールしたかったのですが、最新のsimplejson
バージョンが実際には3.3.0であることがわかったので、更新してタイムテストを再実行しました。
simplejson
は、ロード時に組み込みのjson
の約3倍高速です。simplejson
は、ダンプ時に組み込みのjson
よりも約30%高速です。上記のステートメントはpython-2.7.3とsimplejson 3.3.0(cスピードアップ付き)にあり、私の答えも時間に敏感ではないことを確認するために、独自のテストを実行する必要がありますバージョン間で大きく異なるため、チェックする。時間に敏感ではない簡単な答えはありません。
import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, '_speedups', False))
UPDATE:最近、 json というライブラリに遭遇しました。これは、いくつかの基本的なテストでsimplejson
よりも約3倍高速です。
Json、simplejson、cjsonのベンチマークを行ってきました。
$ 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]'
私が見つけた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)
これは修正できません issue 4
組み込みのjson
モジュールがPython 2.6に含まれました。 Python <2.6のバージョンをサポートするプロジェクトには、フォールバックが必要です。多くの場合、そのフォールバックはsimplejson
です。
プロジェクトがsimplejsonを使用するもう1つの理由は、組み込みのjsonに元々Cの高速化が含まれていなかったため、パフォーマンスの違いが顕著であったことです。
Python jsonライブラリの(現在は時代遅れの)比較を次に示します。
Python用のJSONモジュールの比較 ( アーカイブリンク )
この比較の結果に関係なく、Python 2.6を使用している場合は、標準ライブラリjsonを使用する必要があります。そして..もそうでなければsimplejsonを使用するかもしれません。
Python3では、b'bytes'
の文字列で、json
を使用する場合、ロードする前にコンテンツを.decode()
する必要があります。 simplejson
がこれを処理するので、単にsimplejson.loads(byte_string)
を実行できます。
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を使用しないのですか?
Python 2.6のsimplejsonをインストールしようとしていたときに、この質問に出会いました。 jsonファイルをOrderedDictとしてロードするには、json.load()の 'object_pairs_hook'を使用する必要がありました。 Pythonの最新バージョンに精通しているため、Python 2.6のjsonモジュールに 'object_pairs_hook'が含まれていないことに気づかなかったため、この目的のためにsimplejsonをインストールする必要がありました。個人的な経験から、これが標準のjsonモジュールではなくsimplejsonを使用する理由です。