Самый быстрый способ сохранить и загрузить большой словарь в Python
У меня есть относительно большой словарь. Как я узнаю размер? хорошо, когда я сохраняю это с помощью cPickle
размер файла вырастет ок. 400MB. cPickle
должен быть намного быстрее, чем pickle
но загрузка и сохранение этого файла просто занимает много времени. У меня есть двухъядерный ноутбук 2,6 ГГц с 4 ГБ оперативной памяти на компьютере с Linux. У кого-нибудь есть предложения по более быстрому сохранению и загрузке словарей в python? Спасибо
5 ответов
Используйте параметр protocol=2 cPickle. Протокол по умолчанию (0) намного медленнее и создает файлы большего размера на диске.
Если вы просто хотите работать со словарем большего размера, чем может вместить память, модуль shelve - это хорошее и быстрое решение. Он действует как диктовка в памяти, но сохраняет себя на диске, а не в памяти. Полка основана на cPickle, поэтому обязательно установите для вашего протокола значение, отличное от 0.
Преимущества такой базы данных, как sqlite перед cPickle, будут зависеть от вашего варианта использования. Как часто вы будете писать данные? Сколько раз вы ожидаете прочитать каждый элемент данных, который вы пишете? Вы когда-нибудь захотите выполнить поиск данных, которые вы пишете, или загрузить их по одному фрагменту за раз?
Если вы выполняете однократную запись, чтение и загрузку одного фрагмента за раз, обязательно используйте базу данных. Если вы делаете запись один раз, прочитайте один раз, cPickle (с любым протоколом, отличным от протокола по умолчанию =0) будет трудно победить. Если вы просто хотите большой, постоянный диктат, используйте полку.
Я знаю, что это старый вопрос, но просто как обновление для тех, кто все еще ищет ответ на этот вопрос: protocol
Аргумент был обновлен в Python 3, и теперь есть еще более быстрые и эффективные варианты (т.е. protocol=3
а также protocol=4
), которая может не работать под python 2. Вы можете прочитать об этом больше в ссылке.
Чтобы всегда использовать лучший протокол, поддерживаемый используемой версией Python, вы можете просто использовать pickle.HIGHEST_PROTOCOL
, Следующий пример взят из ссылки:
import pickle
# ...
with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
Я пробовал это для многих проектов и пришел к выводу, что shelve
быстрее чем pickle
в сохранении данных. Оба работают одинаково при загрузке данных.
Shelve
на самом деле грязное решение. Это потому, что с этим нужно быть очень осторожным. Если вы не закроетеshelve
файл после его открытия или по какой-либо причине в вашем коде происходит прерывание, когда вы открываете и закрываете его, shelve
файл имеет высокий шанс быть поврежденным (что приводит к возникновению ошибок KeyErrors); что действительно раздражает, учитывая, что мы, которые их используем, заинтересованы в них из-за хранения наших БОЛЬШИХ файлов dict, создание которых, очевидно, также заняло много времени. Вот почему полка - грязное решение... Но все же быстрее. Так!
Sqlite
Возможно, стоит хранить данные в базе данных Sqlite. Хотя при рефакторинге вашей программы для работы с Sqlite будут возникать некоторые накладные расходы на разработку, также будет намного проще и эффективнее запрашивать базу данных.
Вы также получаете транзакции, атомарность, сериализацию, сжатие и т. Д. Бесплатно.
В зависимости от того, какую версию Python вы используете, у вас может быть встроенный sqlite.
Вы можете проверить сжатие своего словаря (с некоторыми ограничениями, см. Этот пост), это будет эффективно, если доступ к диску является узким местом.
Это много данных... Какое содержание имеет ваш словарь? Если это только примитивные или фиксированные типы данных, может быть, лучше использовать реальную базу данных или пользовательский формат файла?