Рассол или JSON?
мне нужно сохранить на диск немного dict
объект, ключи которого имеют тип str
и значения int
s а потом восстановить его. Что-то вроде этого:
{'juanjo': 2, 'pedro':99, 'other': 333}
что является лучшим вариантом и почему? Сериализуйте его с помощью pickle
или simplejson
?
Я использую Python 2.6.
7 ответов:
Если у вас нет никаких требований к совместимости (например, вы просто собираетесь использовать данные с Python), и двоичный формат в порядке, идите с cPickle что дает вам очень быструю сериализацию объектов Python.
Если вам нужна совместимость или вы хотите, чтобы текстовый формат хранил ваши данные, перейдите в JSON (или какой-либо другой подходящий формат в зависимости от ваших ограничений).
Я предпочитаю JSON над рассолом для моей сериализации. Распаковка может запускать произвольный код, а с помощью
pickle
для передачи данных между программами или хранение данных между сеансами-это дыра в безопасности. JSON не вводит дыру в безопасности и стандартизирован, поэтому данные могут быть доступны программами на разных языках, если вам когда-либо понадобится.
вы также можете найти это интересным, с некоторыми диаграммами для сравнения:http://kovshenin.com/archives/pickle-vs-json-which-is-faster/
Если вы в первую очередь связаны со скоростью и пространством, используйте cPickle, потому что cPickle быстрее, чем JSON.
Если вы больше заинтересованы в совместимости, безопасности и / или удобочитаемости человека, то используйте JSON.
результаты тестов, на которые ссылаются в других ответах, были записаны в 2010 году, а обновленные тесты в 2016 году с cPickle протокол 2 показать:
- cPickle 3.8 x быстрее загрузка
- cPickle 1.5 x более быстрое чтение
- 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 на приличном процессоре 2015 Xeon:
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 -
JSON или рассол? Как насчет JSON и огурчик! Вы можете использовать
jsonpickle
. Он прост в использовании, и файл на диске читается, потому что это JSON.
лично я обычно предпочитаю JSON, потому что данные удобочитаемое. Определенно, Если вам нужно сериализовать что-то, что JSON не возьмет, чем использовать pickle.
но для большинства хранилищ данных вам не нужно будет сериализовать что-то странное, а JSON намного проще и всегда позволяет вам открыть его в текстовом редакторе и проверить данные самостоятельно.
скорость хорошая, но для большинства наборов данных разница незначительна; Python обычно не слишком быстро в любом случае.
я попробовал несколько методов и обнаружил, что с помощью 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