У меня есть приложение Python GAE, которое хранит данные в каждом экземпляре, и использование памяти намного выше, чем я ожидал. В качестве иллюстрации рассмотрим этот тестовый код, который я добавил в свое приложение:
from google.appengine.ext import webapp
bucket = []
class Memory(webapp.RequestHandler):
def get(self):
global bucket
n = int(self.request.get('n'))
size = 0
for i in range(n):
text = '%10d' % i
bucket.append(text)
size += len(text)
self.response.out.write('Total number of characters = %d' % size)
Вызов этого обработчика со значением переменной запроса n приведет к тому, что экземпляр добавит в свой список n строк, каждая из которых имеет длину 10 символов.
Если я вызову это с n=1 (чтобы все было загружено), а затем проверю использование памяти экземпляра на рабочем сервере, я увижу цифру 29,4 МБ. Если я затем вызову его с n=100000 и снова проверю, использование памяти подскочило до 38,9 МБ. То есть объем моей памяти увеличился на 9,5 МБ, чтобы хранить всего один миллион символов, что почти в десять раз больше, чем я ожидал. Я считаю, что символы потребляют только один байт каждый, но даже если это неправильно, нам еще предстоит пройти долгий путь. Накладные расходы на структуру списка, конечно, не могут объяснить этого. Я попытался добавить явный вызов сборки мусора, но цифры не изменились. Что мне не хватает, и есть ли способ уменьшить занимаемую площадь?
(Между прочим, я попытался использовать набор вместо списка и обнаружил, что после вызова с n=100000 использование памяти увеличилось на 13 МБ. Это говорит о том, что накладные расходы набора для 100000 строк на 3,5 МБ больше, чем для списков, что также намного больше. больше, чем ожидалось.)