Quais são as diferenças entre os módulos JSON e Simplejson Python?
-
23-08-2019 - |
Pergunta
Eu já vi muitos projetos usando simplejson
módulo em vez de json
módulo da biblioteca padrão. Além disso, existem muitos diferentes simplejson
módulos. Por que usaria essas alternativas, em vez de uma na biblioteca padrão?
Solução
json
é simplejson
, adicionado ao stdlib. Mas desde json
foi adicionado em 2.6, simplejson
Tem a vantagem de trabalhar em mais versões Python (2.4+).
simplejson
também é atualizado com mais frequência do que o python; portanto, se você precisar (ou desejar) a versão mais recente, é melhor usar simplejson
por si só, se possível.
Uma boa prática, na minha opinião, é usar um ou outro como um retorno.
try:
import simplejson as json
except ImportError:
import json
Outras dicas
Eu tenho que discordar das outras respostas: os incorporados json
Biblioteca (no Python 2.7) não é necessariamente mais lenta do que simplejson
. Também não tem Este inseto de unicode irritante.
Aqui está uma referência simples:
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)
E os resultados no meu sistema (Python 2.7.4, Linux 64 bits):
Dados complexos do mundo real:
JSON despeja 1.56666707993 segundos
Simplejson despeja 2.25638604164 segundos
JSON carrega 2.71256899834 segundos
Simplejson carrega 1.29233884811 segundosDados simples:
JSON despeja 0,370109081268 segundos
Simplejson despeja 0,574181079865 segundos
JSON carrega 0,422876119614 segundos
Simplejson carrega 0,270955085754 segundos
Para despejar, json
é mais rápido que simplejson
. Para carregar, simplejson
é mais rápido.
Desde que estou construindo um serviço da web atualmente, dumps()
é mais importante - e o uso de uma biblioteca padrão é sempre preferido.
Também, cjson
Não foi atualizado nos últimos 4 anos, então eu não tocaria.
Todas essas respostas não são muito úteis porque são tempo sensível.
Depois de fazer algumas pesquisas minhas, descobri que simplejson
é realmente mais rápido que o embutido, E se Você o mantém atualizado para a versão mais recente.
pip/easy_install
queria instalar 2.3.2 no Ubuntu 12.04, mas depois de descobrir o mais recente simplejson
A versão é na verdade 3.3.0, então eu a atualizei e re -os testes de tempo.
simplejson
é cerca de 3x mais rápido que o embutidojson
em cargassimplejson
é cerca de 30% mais rápido que o embutidojson
em lixões
Isenção de responsabilidade:
As declarações acima estão em Python-2.7.3 e Simplejson 3.3.0 (com acepessos C) e para garantir que minha resposta também não seja sensível ao tempo, você deve Execute seus próprios testes verificar, pois varia muito entre as versões; Não há resposta fácil que não seja sensível ao tempo.
Como saber se as acelerações C são ativadas no Simplejson:
import simplejson
# If this is True, then c speedups are enabled.
print bool(getattr(simplejson, '_speedups', False))
ATUALIZAR: Recentemente me deparei com uma biblioteca chamada ujson que está realizando ~ 3x mais rápido que simplejson
com alguns testes básicos.
Eu tenho benchmarking JSON, Simplejson e Cjson.
- CJSON é mais rápido
- Simplejson está quase em pé de igualdade com o cjson
- JSON é cerca de 10x mais lento que o simplesjson
$ 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
Alguns valores são serializados de maneira diferente entre Simplejson e JSON.
Notavelmente, instâncias de collections.namedtuple
são serializados como matrizes por json
mas como objetos por simplejson
. Você pode substituir esse comportamento passando namedtuple_as_object=False
para simplejson.dump
, mas, por padrão, os comportamentos não correspondem.
>>> 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]'
Uma incompatibilidade da API que encontrei, com o Python 2.7 vs Simplejson 3.3.1 está em saber se a saída produz objetos STR ou Unicode. por exemplo
>>> 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'}
Se a preferência é usar o Simplejson, isso pode ser abordado coagindo a string de argumento para unicode, como em:
>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode(unicode("""{ "a":"b" }""", "utf-8"))
{u'a': u'b'}
A coerção exige conhecer o charset original, por exemplo:
>>> 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)
Este é o não consertar Edição 40
O embutido json
O módulo foi incluído no Python 2.6. Quaisquer projetos que suportem versões do Python <2,6 precisam ter um retorno. Em muitos casos, esse fallback é simplejson
.
Outro motivo pelo qual os projetos usam o Simplejson é que o JSON incorporado não incluiu originalmente suas acelerações C, de modo que a diferença de desempenho era perceptível.
Aqui está (uma comparação (agora desatualizada) das bibliotecas Python JSON:
Comparando módulos JSON para Python (Link de arquivo)
Independentemente dos resultados nesta comparação, você deve usar o JSON da biblioteca padrão se estiver no Python 2.6. E .. poderia muito bem usar o Simplejson de outra forma.
O módulo Simplejson é simplesmente 1,5 vezes mais rápido que o JSON (no meu computador, com o Simplejson 2.1.1 e o Python 2.7 x86).
Se quiser, você pode tentar o benchmark: http://abral.altervista.org/jsonpickle-bench.zipNo meu PC Simplejson é mais rápido que o CPICKLE. Eu gostaria de saber também seus benchmarks!
Provavelmente, como disse Coady, a diferença entre Simplejson e JSON é que o Simplejson inclui _speedups.c. Então, por que os desenvolvedores do Python não usam o Simplejson?
Em python3, se você uma série de b'bytes'
, com json
você tem que .decode()
o conteúdo antes que você possa carregá -lo. simplejson
cuida disso para que você possa fazer simplejson.loads(byte_string)
.
Eu me deparei com essa pergunta, pois estava procurando instalar o Simplejson para o Python 2.6. Eu precisava usar o 'object_pairs_hook' de json.load () para carregar um arquivo json como um ordenado. Estando familiarizado com as versões mais recentes do Python, não percebi que o módulo JSON do Python 2.6 não inclui o 'object_pairs_hook', então tive que instalar o Simplejson para esse fim. Da experiência pessoal, é por isso que uso o Simplejson em oposição ao módulo JSON padrão.