Я должен оптимизировать Использование оперативной памяти своего приложения.
Сэкономьте меня лекции, говоря мне, я не должен заботиться о памяти при кодировании 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 - я не забочусь, ужасна ли эта очень маленькая часть кода. Это - просто исключительное местоположение.
Заранее спасибо!
Для веб-приложения вы должны использовать базу данных, в том виде, в котором вы это делаете, вы создаете одну копию вашей дикты для каждого процесса apache, что крайне расточительно. Если у вас достаточно памяти на сервере, таблица базы данных будет кэшироваться в памяти (если у вас недостаточно памяти для одной копии вашей таблицы, поставьте больше оперативной памяти на сервер). Только не забудьте поставить правильные индексы для вашей таблицы базы данных, иначе вы получите плохую производительность.
Используйте полку
или базу данных для хранения данных вместо dict в памяти.
Если вы хотите провести глубокую оптимизацию и иметь полный контроль над использованием памяти, вы также можете написать модуль на C/C++. Используя Swig, можно легко сделать обертку кода в Python, с небольшим превышением производительности по сравнению с чистым C Python модулем.
Если вы хотите использовать хранилище данных в памяти, вы можете попробовать что-нибудь вроде memcached .
Таким образом, вы можете использовать одно хранилище ключей / значений в памяти из всех процессов Python.
Существует несколько клиентских библиотек python memcached.
Redis будет отличным вариантом, если у вас есть возможность использовать его на общем хосте - он похож на memcached, но оптимизирован для структур данных. Redis также поддерживает привязку к python.
Я использую его на ежедневной основе для подсчета чисел, а также в производственных системах в качестве хранилища данных и не могу рекомендовать его достаточно высоко.
Также, есть ли у вас возможность проксировать ваше приложение за nginx вместо использования Apache? Вы можете обнаружить (если это разрешено), что такая схема прокси/webapp менее требовательна к ресурсам.
Удачи.
У меня были ситуации, когда у меня был набор больших объектов, которые мне нужно было отсортировать и отфильтровать различными методами на основе нескольких свойств метаданных. Мне не понадобились их большие части, поэтому я выгрузил их на диск.
Поскольку ваши данные настолько просты по типу, быстрая база данных SQLite может решить все ваши проблемы и даже немного ускорить процесс.