Подсказки Python для оптимизации памяти

Я должен оптимизировать Использование оперативной памяти своего приложения.
Сэкономьте меня лекции, говоря мне, я не должен заботиться о памяти при кодировании Python. У меня есть проблема памяти, потому что я использую очень большие словари по умолчанию (да, я также хочу быть быстрым). Мое текущее потребление памяти составляет 350 МБ и рост. Я уже не могу использовать совместно использованный хостинг и если мой Apache открывает больше процессов, память удваивается и утраивается..., и это дорого.
Я сделал обширное профилирование, и я знаю точно, где мои проблемы.
У меня есть несколько большие (> 100K записи) словари с ключами Unicode. Словарь запускается на уровне 140 байтов и быстро растет, но большей проблемой являются ключи. Python оптимизирует строки в памяти (или таким образом, я читал) так, чтобы поиски могли быть идентификационными сравнениями ('интернирующий' их). Не уверенный это также верно для строк unicode (я не смог 'интернировать' их).
Объекты, хранившие в словаре, являются списками кортежей (an_object, интервал, интервал).

my_big_dict [some_unicode_string] .append ((my_object, an_int, another_int))

Я уже нашел, что имеет смысл разделять к нескольким словарям, потому что кортежи занимают много места...
Я нашел, что мог сохранить RAM путем хеширования строк перед использованием их как ключи! Но затем, к сожалению, я столкнулся с коллизиями дня рождения в своей системе на 32 бита. (вопрос о стороне: существует ли 64-разрядный ключевой словарь, который я могу использовать в 32-разрядной системе?)

Python 2.6.5 и на Linux (производство) и на Windows. Какие-либо подсказки относительно оптимизации использования памяти словарей / перечисляют / кортежи? Я даже думал об использовании C - я не забочусь, ужасна ли эта очень маленькая часть кода. Это - просто исключительное местоположение.

Заранее спасибо!

10
задан Tal Weiss 18 July 2013 в 18:04
поделиться

6 ответов

Для веб-приложения вы должны использовать базу данных, в том виде, в котором вы это делаете, вы создаете одну копию вашей дикты для каждого процесса apache, что крайне расточительно. Если у вас достаточно памяти на сервере, таблица базы данных будет кэшироваться в памяти (если у вас недостаточно памяти для одной копии вашей таблицы, поставьте больше оперативной памяти на сервер). Только не забудьте поставить правильные индексы для вашей таблицы базы данных, иначе вы получите плохую производительность.

4
ответ дан 3 December 2019 в 19:31
поделиться

Используйте полку или базу данных для хранения данных вместо dict в памяти.

1
ответ дан 3 December 2019 в 19:31
поделиться

Если вы хотите провести глубокую оптимизацию и иметь полный контроль над использованием памяти, вы также можете написать модуль на C/C++. Используя Swig, можно легко сделать обертку кода в Python, с небольшим превышением производительности по сравнению с чистым C Python модулем.

0
ответ дан 3 December 2019 в 19:31
поделиться

Если вы хотите использовать хранилище данных в памяти, вы можете попробовать что-нибудь вроде memcached .

Таким образом, вы можете использовать одно хранилище ключей / значений в памяти из всех процессов Python.

Существует несколько клиентских библиотек python memcached.

1
ответ дан 3 December 2019 в 19:31
поделиться

Redis будет отличным вариантом, если у вас есть возможность использовать его на общем хосте - он похож на memcached, но оптимизирован для структур данных. Redis также поддерживает привязку к python.

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

Также, есть ли у вас возможность проксировать ваше приложение за nginx вместо использования Apache? Вы можете обнаружить (если это разрешено), что такая схема прокси/webapp менее требовательна к ресурсам.

Удачи.

1
ответ дан 3 December 2019 в 19:31
поделиться

У меня были ситуации, когда у меня был набор больших объектов, которые мне нужно было отсортировать и отфильтровать различными методами на основе нескольких свойств метаданных. Мне не понадобились их большие части, поэтому я выгрузил их на диск.

Поскольку ваши данные настолько просты по типу, быстрая база данных SQLite может решить все ваши проблемы и даже немного ускорить процесс.

2
ответ дан 3 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: