Python Slow OutofMemory Ошибка
-
25-09-2019 - |
Вопрос
У меня есть некоторые данные, хранящиеся в БД, которые я хочу обрабатывать. Доступ DB болезненно медленный, поэтому я решил загрузить все данные в словаре перед любой обработкой. Однако из-за огромного размера хранимых данных я получаю ошибку памяти (я вижу более 2 гигов). Поэтому я решил использовать структуру данных диска и обнаружил, что использование SHELVE - это опция. Вот что я делаю (Pseudo Python код)
def loadData():
if (#dict exists on disk):
d = shelve.open(name)
return d
else:
d = shelve.open(name, writeback=True)
#access DB and write data to dict
# d[key] = value
# or for mutable values
# oldValue = d[key]
# newValue = f(oldValue)
# d[key] = newValue
d.close()
d = shelve.open(name, writeback=True)
return d
У меня есть пара вопросов,
1) Мне действительно нужна запись = true? Что оно делает?
2) Я до сих пор получаю исключение на неоправданной среде, так как я не тренируюсь, когда данные записываются на диск. Как я могу это сделать? Я попытался сделать синхронизм () каждые несколько итераций, но это тоже не помогло.
Спасибо!
Решение
writeback=True
заставляет полку хранить в памяти любой предмет когда-либо привлеченный, и записываю их, когда полка закрыта. Итак, он потребляет гораздо больше памяти и замедляет закрытие.
Преимущество параметра это то, что, с ним, вы нет Нужен арендованный код, который вы показываете в своем комментарии для мусорных элементов, мутатор которых является методом - просто
shelf['foobar'].append(23)
работает (если shelf
был открыт с включенным обращитом списка), предполагая элемент на ключ 'foobar'
это список конечно, в то время как он молча будет не работает (оставив предмет на диске без изменений), если shelf
был открыт без прививки - в последнем случае вам действительно нужно кодировать
thelist = shelf['foobar']
thelist.append(23)
shekf['foobar'] = thelist
В духе вашего комментария - который стилистически несколько из обломка.
Тем не менее, так как вы являются имея проблемы с памятью, я определенно рекомендую нет используя эту сомнительную опцию обратка. Я думаю, что могу назвать это «сомнительным», так как я был тем, который предлагал и сначала реализую его, но это было много лет назад, и я в основном раскаялся за это - это все больше сил пунктность (как ваши Q до Позволяет элегантность и удобство в движущемся коде изначально написано для работы с дикторами (которые будут использовать первую IDIOM, а не вторую и, таким образом, нужно переписывать, чтобы быть использованным с полками без трассировки). Ах ну, извините, это сделал кажется хорошей идеей в то время.
Другие советы
С использованием sqlite3
Модуль, вероятно, ваш лучший выбор здесь. В любом случае, вы можете использовать SQLite полностью в памяти, так как следа памяти может быть немного меньше, чем использование объектов Python в любом случае. Это, как правило, лучший выбор, чем использование shelve
в любом случае; shelve
использует pickle
внизу, что редко то, что вы хотите.
Черт, вы можете просто преобразовать всю вашу существующую базу данных в базу данных SQLite. SQLite хороший и быстрый.