Почему загрузка объекта pickle занимает намного больше времени, чем загрузка файла?
Я заметил, что загрузка словаря из 5000 объектов с помощью pickle занимает много времени (минуты), но загрузка json файла из 5000 объектов занимает короткое время (секунды). Я знаю, что в общем случае объекты идут с некоторыми накладными расходами - и что в ООП накладные расходы, связанные с отслеживанием таких объектов, являются частью стоимости за простоту их использования. Но почему загрузка протравленного объекта занимает так много времени. Что происходит под капотом? Каковы затраты, связанные с сериализацией объекта, в отличие от простой записи его данных в файл? Восстанавливает ли травление объект в тех же местах памяти или что-то еще? (Может быть, убрать другие объекты с дороги). Если сериализация загружается медленнее (по крайней мере, мариновать), то в чем выгода?
2 ответа
Предполагая, что вы используете стандарт Python 2.7 pickle
а также json
модули...
- Python 2.7 использует чисто Python-реализацию
pickle
модуль по умолчанию, хотя более быстрая реализация C доступна. http://docs.python.org/2/library/pickle.html - И наоборот, Python 2.7 использует оптимизированную реализацию C
json
модуль по умолчанию: http://docs.python.org/dev/whatsnew/2.7.html
Таким образом, вы в основном сравниваете десериализатор с чистым Python с оптимизированным десериализатором Си. Неверное сравнение, даже если форматы сериализации были идентичны.
Существуют сравнения скорости для сериализации отдельных объектов, сравнения JSON, pickle и cPickle. Скорость каждого объекта будет отличаться в каждом формате. JSON обычно сравнительно быстрее, чем рассол, и вы часто слышите, что не используете рассол, потому что он небезопасен. Причиной проблем безопасности и некоторой задержки в скорости является то, что pickle на самом деле не сериализует слишком много данных - вместо этого он сериализует некоторые данные и набор инструкций, где инструкции используются для сборки объектов python. Если вы когда-либо смотрели на dis
В модуле вы увидите тип инструкций, которые pickle использует для каждого объекта. cPickle, как и json, не является чистым python и использует оптимизированный C, поэтому он часто быстрее.
Как правило, процесс травления должен занимать меньше места, чем хранение самого объекта - в целом, однако, некоторые наборы команд могут быть довольно большими. JSON имеет тенденцию быть меньше... и удобочитаемым для человека... однако, поскольку json хранит все в виде читаемых человеком строк... он не может сериализовать столько разных типов объектов, сколько могут использовать pickle и cPickle. Таким образом, компромиссом между json является "безопасность" (или негибкость, в зависимости от вашей перспективы) и удобочитаемость по сравнению с рассолом с более широким диапазоном объектов, которые он может сериализовать.
Еще одна веская причина выбора pickle (вместо json) заключается в том, что вы можете легко расширять pickle, что означает, что вы можете зарегистрировать новый метод для сериализации объекта, который не знает, как pickle. Python дает вам несколько способов сделать это... __getstate__
а также __setstate__
так же хорошо как copy_reg
метод. Используя эти методы, вы обнаружите, что люди расширили pickle для сериализации большинства объектов Python, например dill
,
Травление не восстанавливает объекты в той же области памяти. Тем не менее, он восстанавливает объект до того же состояния (как правило), когда он был травлен. Если вы хотите увидеть некоторые причины, по которым люди мариноваются, посмотрите здесь:
Сериализация Python - почему мариновать?
http://nbviewer.ipython.org/gist/minrk/5241793
http://matthewrocklin.com/blog/work/2013/12/05/Parallelism-and-Serialization/