Подтвердить что ты не робот

Python Disk-Based Dictionary

Я запускал какой-то динамический программный код (попытка грубой силы опровергнуть гипотезу Collatz = P), и я использовал dict для хранения длин цепей, которые я уже вычислил. Очевидно, в какой-то момент у него не хватило памяти. Есть ли какой-либо простой способ использовать какой-либо вариант dict, который выведет страницы на диск, когда он закончится? Очевидно, это будет медленнее, чем встроенный dict, и это, вероятно, закончится тем, что поедает мое пространство на жестком диске, но это может относиться к другим проблемам, которые не так бесполезны.

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

Является ли самый умный способ создать собственный набор диктов, сохраняя только один в памяти за раз, и выставляя их подкачку каким-то эффективным образом?

4b9b3361

Ответ 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 - довольно хороший кодер). Может быть, вы могли бы попробовать?

Ответ 8

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

Ответ 9

Я еще не пробовал, но Hamster DB является многообещающим и имеет интерфейс Python.