Рассол или JSON? - PullRequest
       6

Рассол или JSON?

104 голосов
/ 14 февраля 2010

Мне нужно сохранить на диск небольшой dict объект, ключи которого имеют тип str и значения int s , а затем восстановить его . Как то так:

{'juanjo': 2, 'pedro':99, 'other': 333}

Какой вариант лучше и почему? Сериализуйте его с помощью pickle или simplejson?

Я использую Python 2.6.

Ответы [ 7 ]

91 голосов
/ 14 февраля 2010

Я предпочитаю JSON вместо pickle для моей сериализации. Разбрасывание может запускать произвольный код, а использование pickle для передачи данных между программами или хранения данных между сеансами является дырой в безопасности. JSON не вводит дыру в безопасности и стандартизирован, поэтому к данным могут обращаться программы на разных языках, если вам когда-либо понадобится.

62 голосов
/ 14 февраля 2010

Если у вас нет каких-либо требований к взаимодействию (например, вы просто собираетесь использовать данные с Python) и двоичный формат в порядке, используйте cPickle , который дает вам действительно быструю сериализацию объектов Python.

Если вы хотите функциональной совместимости или хотите, чтобы текстовые форматы сохраняли ваши данные, используйте JSON (или другой подходящий формат в зависимости от ваших ограничений).

42 голосов
/ 02 июня 2011

Вы также можете найти это интересным, с некоторыми графиками для сравнения: http://kovshenin.com/archives/pickle-vs-json-which-is-faster/

19 голосов
/ 21 сентября 2016

Если вас больше всего интересуют скорость и пространство, используйте cPickle, потому что cPickle быстрее, чем JSON.

Если вас больше интересует совместимость, безопасность и / или удобочитаемость, используйте JSON.


Результаты тестов, на которые есть ссылки в других ответах, были записаны в 2010 году, а обновленные тесты в 2016 году с использованием протокола cPickle 2 show:

  • cPickle 3.8x ускоренная загрузка
  • cPickle 1,5 раза быстрее чтения
  • cPickle немного меньшая кодировка

Воспроизведите это сами с этой сущностью , основанной на тесте Константина , указанном в других ответах, но с использованием cPickle с протоколом 2 вместо pickle и использованием json вместо simplejson (поскольку json быстрее, чем simplejson ), например,

wget https://gist.github.com/jdimatteo/af317ef24ccf1b3fa91f4399902bb534/raw/03e8dbab11b5605bc572bc117c8ac34cfa959a70/pickle_vs_json.py
python pickle_vs_json.py

Результаты с python 2.7 на приличном процессоре Xeon 2015:

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 с протоколом рассола 3 еще быстрее.

11 голосов
/ 14 февраля 2010

JSON или рассол? Как насчет рассола JSON и ! Вы можете использовать jsonpickle. Он прост в использовании, и файл на диске читается, потому что это JSON.

http://jsonpickle.github.com/

4 голосов
/ 12 декабря 2017

Я попробовал несколько методов и обнаружил, что использование cPickle с установкой аргумента протокола метода dumps как: cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL) - самый быстрый метод дампа.

import msgpack
import json
import pickle
import timeit
import cPickle
import numpy as np

num_tests = 10

obj = np.random.normal(0.5, 1, [240, 320, 3])

command = 'pickle.dumps(obj)'
setup = 'from __main__ import pickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("pickle:  %f seconds" % result)

command = 'cPickle.dumps(obj)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle:   %f seconds" % result)


command = 'cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle highest:   %f seconds" % result)

command = 'json.dumps(obj.tolist())'
setup = 'from __main__ import json, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("json:   %f seconds" % result)


command = 'msgpack.packb(obj.tolist())'
setup = 'from __main__ import msgpack, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("msgpack:   %f seconds" % result)

Выход:

pickle         :   0.847938 seconds
cPickle        :   0.810384 seconds
cPickle highest:   0.004283 seconds
json           :   1.769215 seconds
msgpack        :   0.270886 seconds
4 голосов
/ 26 июня 2014

Лично я обычно предпочитаю JSON, потому что данные удобочитаемы . Определенно, если вам нужно сериализовать что-то, что JSON не примет, тогда используйте pickle.

Но для большинства хранилищ данных вам не нужно сериализовывать что-то странное, а JSON намного проще и всегда позволяет открыть его в текстовом редакторе и проверить данные самостоятельно.

Скорость хорошая, но для большинства наборов данных разница незначительна; Во всяком случае, Python не слишком быстрый.

...