Pickle ou json?
Eu preciso para salvar no disco um pouco dictobjeto cujas chaves são do tipo stre os valores são ints e depois recuperá-lo . Algo assim:
{'juanjo': 2, 'pedro':99, 'other': 333}
Qual é a melhor opção e por quê? Serializar com pickleou com simplejson?
Estou usando o Python 2.6.
— Juanjo Conti
convertê-lo em quê? Além disso, em que sentido melhor ?
No 2.6 você não usaria simplejson, usaria o jsonmódulo embutido (que tem exatamente a mesma interface).
"melhor"? Melhor para quê? Rapidez? Complexidade? Flexibilidade? Custo?
veja também stackoverflow.com/questions/8968884/…
@Trilarion: YAML é um superconjunto de JSON
Se você não tem nenhum requisito de interoperabilidade (por exemplo, você vai apenas usar os dados com Python) e um formato binário está bom, vá com cPickle que fornece serialização de objetos Python muito rápida.
Se você deseja interoperabilidade ou um formato de texto para armazenar seus dados, use JSON (ou algum outro formato apropriado, dependendo de suas restrições).
— Håvard S
JSON parece ser mais rápido do que cPickle.
Minha resposta destaca as preocupações que considero mais importantes a serem consideradas ao escolher qualquer uma das soluções. Eu não afirmo sobre ser mais rápido do que o outro. Se JSON for mais rápido E adequado de outra forma, vá com JSON! (
My point is: there is no real reason for using cPickle (or pickle) based on your premises over JSON. When I first read your answer I thought the reason might have been speed, but since this is not the case... :)
O benchmark citado por @mac testa apenas strings. Eu testei str, int e float separadamente e descobri que json é mais lento que cPickle com serialização de float, mas mais rápido com desserialização de float. Para int (e str), json é mais rápido em ambos os sentidos. Dados e código: gist.github.com/marians/f1314446b8bf4d34e782
O protocolo mais recente do cPickle agora é mais rápido do que JSON. O comentário votado sobre JSON ser mais rápido está desatualizado em alguns anos. stackoverflow.com/a/39607169/1007353
— JDiMatteo
Eu prefiro JSON em vez de pickle para minha serialização. O Unpickling pode executar código arbitrário e usar picklepara transferir dados entre programas ou armazenar dados entre sessões é uma falha de segurança. JSON não apresenta uma falha de segurança e é padronizado, portanto, os dados podem ser acessados ​​por programas em diferentes linguagens se você precisar.
Obrigado. De qualquer forma, estarei despejando e carregando no mesmo programa.
Embora os riscos de segurança possam ser baixos em seu aplicativo atual, o JSON permite que você feche o todo.
One can create a pickle-virus that pickles itself into everything that is pickled after loaded. With json this is not possible.
Além da segurança, o JSON tem a vantagem adicional de facilitar as migrações, para que você possa carregar dados salvos por uma versão mais antiga do seu aplicativo. Enquanto isso, você poderia ter adicionado um campo ou substituído uma subestrutura inteira. Escrever tal conversor (migração) para dict / list é simples, mas com o Pickle você terá dificuldade em carregá-lo em primeiro lugar, antes mesmo de pensar em converter.
Eu não tinha pensado sobre esse aspecto (segurança e a capacidade de objetos em conserva rodarem código arbitrário). Obrigado por apontar isso!
— CaffeinatedMike
Você também pode achar isso interessante, com alguns gráficos para comparar: http://kovshenin.com/archives/pickle-vs-json-which-is-faster/
O artigo compara o desempenho apenas relacionado a strings. Aqui está um script que você pode executar para testar strings, floats e ints separadamente: gist.github.com/marians/f1314446b8bf4d34e782
Em Python 3.4, picklebate jsonna int, stre float.
Se você está preocupado principalmente com velocidade e espaço, use cPickle porque cPickle é mais rápido que JSON.
Se você está mais preocupado com interoperabilidade, segurança e / ou legibilidade humana, use JSON.
Os resultados dos testes referenciados em outras respostas foram registrados em 2010, e os testes atualizados em 2016 com protocolo cPickle 2 mostram:
Carregamento cPickle 3,8x mais rápido
cPickle 1.5x mais rápido
Codificação cPickle ligeiramente menor
Reproduza você mesmo com esta essência , que é baseada no benchmark de Konstantin referenciado em outras respostas, mas usando cPickle com protocolo 2 em vez de pickle, e usando json em vez de simplejson (já que json é mais rápido que simplejson ), por exemplo,
wget https://gist.github.com/jdimatteo/af317ef24ccf1b3fa91f4399902bb534/raw/03e8dbab11b5605bc572bc117c8ac34cfa959a70/pickle_vs_json.py
python pickle_vs_json.py
Resultados com o python 2.7 em um processador Xeon 2015 decente:
Dir Entries Method  Time    Length
dump    10  JSON    0.017   1484510
load    10  JSON    0.375   -
dump    10  Pickle  0.011   1428790
load    10  Pickle  0.098   -
dump    20  JSON    0.036   2969020
load    20  JSON    1.498   -
dump    20  Pickle  0.022   2857580
load    20  Pickle  0.394   -
dump    50  JSON    0.079   7422550
load    50  JSON    9.485   -
dump    50  Pickle  0.055   7143950
load    50  Pickle  2.518   -
dump    100 JSON    0.165   14845100
load    100 JSON    37.730  -
dump    100 Pickle  0.107   14287900
load    100 Pickle  9.907   -
Python 3.4 com protocolo pickle 3 é ainda mais rápido.
JSON ou picles? Que tal JSON e pickle! Você pode usar jsonpickle. É fácil de usar e o arquivo no disco é legível porque é JSON.
— Paul Hildebrandt
Alguém fez o benchmarking de seu desempenho em relação às opções? É comparável em desempenho como json bruto como visto aqui benfrederickson.com/dont-pickle-your-data ?
Este não é um benchmark abrangente, mas eu tinha um jogo onde salvava os níveis usando pickle (python3). Eu queria tentar jsonpickle para o aspecto legível por humanos - no entanto, os salvamentos de nível eram tristemente muito mais lentos. 1597ms para jsonpickle e 88ms ou pickle regular no nível de salvamento. Para carga nivelada, 1604ms para jsonpickle e 388 para pickle. Pena que eu gosto dos arquivos salvos legíveis por humanos.
Eu testei isso em nosso sistema de comércio, a legibilidade vem com cerca de 2x serialização + penalidade de velocidade de desserialização em comparação com pickle. Ótimo para qualquer outra coisa, no entanto.
Eu tentei vários métodos e descobri que usar cPickle com a configuração do argumento de protocolo do método de despejo como: cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)é o método de despejo mais rápido.
— Ahmed Abobakr
Pessoalmente, geralmente prefiro JSON porque os dados são legíveis por humanos . Definitivamente, se você precisar serializar algo que JSON não aceita, use pickle.
Mas para a maioria do armazenamento de dados, você não precisa serializar nada estranho e JSON é muito mais fácil e sempre permite que você o abra em um editor de texto e verifique os dados você mesmo.
A velocidade é boa, mas para a maioria dos conjuntos de dados a diferença é insignificante; Python geralmente não é muito rápido de qualquer maneira.
— rickcnagy
No Python 3.4, pickleé duas vezes mais rápido que json.
Verdade. Mas, para os 100elementos de uma lista, a diferença é completamente desprezível ao olho humano. Definitivamente diferente ao trabalhar com conjuntos de dados maiores.