Python Disk-Based Dictionary
Я запускал какой-то динамический программный код (попытка грубой силы опровергнуть гипотезу Collatz = P), и я использовал dict для хранения длин цепей, которые я уже вычислил. Очевидно, в какой-то момент у него не хватило памяти. Есть ли какой-либо простой способ использовать какой-либо вариант dict
, который выведет страницы на диск, когда он закончится? Очевидно, это будет медленнее, чем встроенный dict, и это, вероятно, закончится тем, что поедает мое пространство на жестком диске, но это может относиться к другим проблемам, которые не так бесполезны.
Я понял, что словарь на основе дисков - это в значительной степени база данных, поэтому я вручную реализовал его с помощью sqlite3, но я не делал этого ни с каких разумных способов и не искал каждый элемент в базе данных по одному за раз... он был примерно в 300 раз медленнее.
Является ли самый умный способ создать собственный набор диктов, сохраняя только один в памяти за раз, и выставляя их подкачку каким-то эффективным образом?
Ответы
Ответ 1
Hash-on-disk обычно адресуется с помощью Berkeley DB или чего-то подобного - несколько параметров перечислены в документации по сохранению данных Python. Вы можете использовать его с кешем в памяти, но сначала я бы тестировал его на основе собственной производительности; с кэшированием операционной системы на месте это может появиться примерно то же самое.
Ответ 2
Также стоит обратить внимание на сторонний модуль shove. Он очень похож на полку в том, что это простой объект, похожий на диктофон, однако он может хранить различные бэкэнд (такие как файл, SVN и S3), обеспечивает дополнительное сжатие и даже поточно-безопасный. Это очень удобный модуль
from shove import Shove
mem_store = Shove()
file_store = Shove('file://mystore')
file_store['key'] = value
Ответ 3
В прошлый раз, когда я столкнулся с такой проблемой, я переписал использование SQLite, а не dict, и имел массовое увеличение производительности. Это увеличение производительности было, по крайней мере, частично за счет возможностей индексирования базы данных; в зависимости от ваших алгоритмов, YMMV.
Тонкая оболочка, которая выполняет запросы SQLite в __getitem__
и __setitem__
, не содержит большого количества кода для записи.
Ответ 4
Модуль shelve может это сделать; во всяком случае, это должно быть просто проверить. Вместо:
self.lengths = {}
делать:
import shelve
self.lengths = shelve.open('lengths.shelf')
Единственный улов в том, что клавиши на полках должны быть строками, поэтому вам придется заменить
self.lengths[indx]
с
self.lengths[str(indx)]
(Я предполагаю, что ваши ключи являются целыми числами, как ваш комментарий к сообщению Чарльза Даффи)
В памяти нет встроенного кэширования, но ваша операционная система может сделать это для вас в любом случае.
[на самом деле, это не совсем так: вы можете передать аргумент "writeback = True" при создании. Цель этого состоит в том, чтобы обеспечить правильное сохранение списков и других изменяемых вещей на полке. Но побочным эффектом является то, что весь словарь кэшируется в памяти. Поскольку это вызвало проблемы для вас, это, вероятно, не очень хорошая идея:-)]
Ответ 5
С небольшим количеством мыслей кажется, что вы можете получить shelve module, чтобы делать то, что вы хотите.
Ответ 6
Я читал, что вы считаете, что полка слишком медленная, и вы пытались взломать свой собственный dict, используя sqlite.
Другой тоже сделал это:
http://sebsauvage.net/python/snyppets/index.html#dbdict
Кажется довольно эффективным (и sebsauvage - довольно хороший кодер). Может быть, вы могли бы попробовать?
Ответ 7
прочитать ответ на этот вопрос из GvR;)
Сортировка миллиона 32-разрядных целых чисел в 2 МБ ОЗУ с использованием Python
Ответ 8
Вы должны принести несколько предметов за раз, если есть какая-то эвристика, чтобы узнать, какие из них наиболее вероятны для последующего поиска, и не забывайте, что такие индексы, как Чарльз, упоминаются.
Ответ 9
Я еще не пробовал, но Hamster DB является многообещающим и имеет интерфейс Python.