표준 라이브러리 simplejson
의 json
모듈 대신 모듈을 사용하는 많은 프로젝트를 보았습니다 . 또한 많은 다른 simplejson
모듈이 있습니다. 표준 라이브러리의 대안 대신 이러한 대안을 사용하는 이유는 무엇입니까?
표준 라이브러리 simplejson
의 json
모듈 대신 모듈을 사용하는 많은 프로젝트를 보았습니다 . 또한 많은 다른 simplejson
모듈이 있습니다. 표준 라이브러리의 대안 대신 이러한 대안을 사용하는 이유는 무엇입니까?
답변:
json
은 simplejson
stdlib에 추가됩니다. 그러나 json
2.6에 추가 된 이후 로 simplejson
더 많은 Python 버전 (2.4+)에서 작업 할 수 있다는 이점이 있습니다.
simplejson
또한 Python보다 더 자주 업데이트되므로 최신 버전이 필요하거나 원하는 경우 사용하는 것이 가장 좋습니다. simplejson
경우 가능하면 자체 하는 것이 .
제 생각에는 좋은 방법은 폴백으로 사용하는 것입니다.
try:
import simplejson as json
except ImportError:
import json
JSONDecodeError
은ValueError
다른 답변에 동의하지 json
않아야합니다 : 내장 라이브러리 (Python 2.7)가 반드시 느릴 필요는 없습니다 simplejson
. 또한 이 성가신 유니 코드 버그 가 없습니다 .
간단한 벤치 마크는 다음과 같습니다.
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
이 빠릅니다.
현재 웹 서비스를 구축 중이므로 dumps()
더 중요하며 표준 라이브러리를 사용하는 것이 항상 선호됩니다.
또한 cjson
지난 4 년 동안 업데이트되지 않았으므로 만지지 않습니다.
json
(CPython 3.5.0)은 simplejson
벤치 마크 코드를 사용하여 C 덤프를 사용하여 단순 덤프에서 68 % | 45 % 더 빠르고 단순 덤프에서는 35 % | 17 % wrt v3.8.0으로 C 속도 향상되었습니다. 따라서이 설정에서는 더 이상 simplejson을 사용하지 않습니다.
json
했으며 모든 테스트에서 승리하거나 동일합니다. 실제로 json
복잡한 실제 데이터 덤프 테스트보다 두 배 빠릅니다.
이 답변은 모두 시간에 민감 하기 때문에 도움이되지 않습니다 .
내 자신의 내가 어떤 연구를하고 후 그 발견 simplejson
, 참으로 빠른 내장보다 경우에 당신이 최신 버전으로 업데이트 유지.
pip/easy_install
우분투 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 포함)에 있으며 내 대답이 시간에 민감하지 않은지 확인하려면 버전마다 매우 다양하므로 자체 테스트 를 실행하여 확인 해야 합니다 . 시간에 민감하지 않은 쉬운 대답은 없습니다.
import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, '_speedups', False))
업데이트 : 최근 에 일부 기본 테스트 보다 ~ 3 배 빠르게 수행되는 ujson 이라는 라이브러리를 발견 했습니다 simplejson
.
나는 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]'
Python 2.7과 simplejson 3.3.1의 API 비 호환성은 출력이 str 또는 유니 코드 객체를 생성하는지 여부에 있습니다. 예 :
>>> from json import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{u'a': u'b'}
vs
>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{'a': 'b'}
환경 설정이 simplejson을 사용하는 경우 다음과 같이 인수 문자열을 유니 코드로 강제 변환하여 해결할 수 있습니다.
>>> 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을 해결하지 않습니다
다음은 Python json 라이브러리에 대한 (현재 구식) 비교입니다.
Python 용 JSON 모듈 비교 ( 아카이브 링크 )
이 비교의 결과에 관계없이 Python 2.6을 사용하는 경우 표준 라이브러리 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가 포함되어 있다는 것입니다. 그렇다면 파이썬 개발자는 왜 simplejson을 사용하지 않습니까?
python3에서 경우의 문자열 b'bytes'
로 json
당신이이 .decode()
내용 당신은 그것을로드 할 수 있습니다 전에. simplejson
당신이 할 수 있도록 이것을 처리 simplejson.loads(byte_string)
합니다.
json
보다 빠르다 simplejson
최신 버전의로드 및 덤프 모두
테스트 된 버전 :
결과 :
>>> 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'}}
버전의 경우 :
덤프 작업 중 json이 simplejson보다 빠르지 만로드 작업 중 동일한 속도를 유지했습니다.
Python 2.6 용 simplejson을 설치하려고 할 때이 질문을 보았습니다. json 파일을 OrderedDict로로드하려면 json.load ()의 'object_pairs_hook'을 사용해야했습니다. 최신 버전의 Python에 익숙하므로 Python 2.6의 json 모듈에 'object_pairs_hook'이 포함되어 있지 않다는 것을 알지 못했기 때문에이 목적을 위해 simplejson을 설치해야했습니다. 개인적인 경험에서 이것은 표준 json 모듈과 달리 simplejson을 사용하는 이유입니다.
redefinition of unused 'json'