2008-10-22 4 views
35

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

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

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

ответ

20

Хеш-на-диске, как правило, адресуется с помощью Berkeley DB или чего-то подобного - несколько параметров перечислены в Python Data Persistence documentation. Вы можете использовать его с кешем в памяти, но сначала я бы тестировал его на основе собственной производительности; с кэшированием операционной системы на месте она может появиться примерно одинаково.

6

В прошлый раз, когда я столкнулся с такой проблемой, я переписал использование SQLite, а не dict, и имел значительное увеличение производительности. Это увеличение производительности было, по крайней мере, частично за счет возможностей индексирования базы данных; в зависимости от ваших алгоритмов, YMMV.

Тонкая обертка, которая выполняет запросы SQLite в __getitem__ и __setitem__, не содержит большого количества кода для написания.

+0

Как именно вы используете индексирование sqlite? то, как я сделал это здесь, было создание таблицы следующим образом: «cur.execute (« create table vals (indx INTEGER, chainlen INTEGER) »), затем я« cur.execute »(« SELECT * from vals, где indx =% d '% i) "для поиска. – Claudiu 2008-10-22 17:50:07

+2

create table vals (indx INTEGER PRIMARY KEY, chainlen INTEGER) – 2008-10-22 17:52:50

+0

@Claudiu - моя программа была такой, что я мог бы реализовать некоторую логику в слое базы данных, поэтому я мог бы позволить БД делать фильтрацию и тому подобное; это было больше, чем просто немой магазин. – 2008-10-23 01:58:59

0

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

2

С небольшим количеством мыслей кажется, что вы можете получить shelve module, чтобы сделать то, что вы хотите.

6

Модуль shelve может это сделать; во всяком случае, это должно быть просто проверить. Вместо того, чтобы:

self.lengths = {} 

сделать:

import shelve 
self.lengths = shelve.open('lengths.shelf') 

Единственная загвоздка в том, что ключи к полкам должны быть строками, так что вам придется заменить

self.lengths[indx] 

с

self.lengths[str(indx)] 

(Я предполагаю, что ваши ключи - это только я ntegers, в соответствии с вашим комментарием к сообщению Чарльза Даффи)

В памяти нет встроенного кэширования, но ваша операционная система может сделать это для вас в любом случае.

[на самом деле это не совсем так: вы можете передать аргумент «writeback = True» при создании. Цель этого состоит в том, чтобы обеспечить правильное сохранение списков и других изменяемых вещей на полке. Но побочным эффектом является то, что весь словарь кэшируется в памяти.Поскольку это вызвало проблемы для вас, это, вероятно, не очень хорошая идея :-)]

52

Модуль 3-го лица shove также стоит взглянуть на него. Он очень похож на полку в том, что это простой объект, похожий на диктофон, однако он может хранить различные бэкэнд (такие как файл, SVN и S3), обеспечивает дополнительное сжатие и даже поточно-безопасный. Это очень удобный модуль

from shove import Shove 

mem_store = Shove() 
file_store = Shove('file://mystore') 

file_store['key'] = value 
0

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

2

Я прочитал вы думаете Shelve слишком медленно, и вы пытались взломать ваш собственный Dict с помощью SQLite.

Другой сделал это слишком:

http://sebsauvage.net/python/snyppets/index.html#dbdict

Это кажется довольно эффективным (и sebsauvage является очень хорошим кодером). Может быть, вы могли бы попробовать?