Я изучаю Python, и я подумал, что это было бы хорошим предлогом для обновления знаний о шаблонах и в этом случае шаблона Flyweight.Flyweight pattern - Memory footprint
Я создал две небольшие программы, которые не оптимизированы, и один из них реализует шаблон Flyweight. Для моих целей тестирования я создаю армию размером 1 000 000 000 000 000 000 000 000 000 000 Каждый враг может быть трех типов (Солдат, Ниндзя или Начальник), и я назначаю девиз каждому типу.
Что я хотел бы проверить, так это то, что с моей не оптимизированной программой я получаю 1'000'000 противников, для каждого и каждого из них, тип и длинную строку, содержащую девиз. С оптимизированным кодом я хотел бы создать только три объекта (EnemyType
), соответствующие каждому типу и содержащие только 3 раза строки девиза. Затем добавляю элемент к каждому Enemy
, указывая на нужный EnemyType
.
Теперь (только отрывки) код:
Un-оптимизированная программа
В этой версии, каждый враг сохраняет свой тип и девиз.
enemyList = [] enemyTypes = {'Soldier' : 'Sir, yes sir!', 'Ninja' : 'Always behind you !', 'Chief' : 'Always behind ... lot of lines '} for i in range(1000000): randomPosX = 0 # random.choice(range(1000)) randomPosY = 0 # random.choice(range(1000)) randomTypeIndex = 0 # random.choice(range(0,len(enemyTypes))) enemyType = enemyTypes.keys()[randomTypeIndex] # Here, the type and motto are parameters of EACH enemy object. enemyList.append(Enemy(randomPosX, randomPosY, enemyType, enemyTypes[enemyType]))
Оптимизированная программа
В этой версии, каждый враг членом
EnemyType
объекта, который хранит его тип и девиз. Созданы только три экземпляраEnemyType
, и я должен увидеть влияние в памяти.enemyList = [] soldierEnemy = EnemyType('Soldier', 'Sir, yes sir!') ninjaEnemy = EnemyType('Ninja', 'Always behind you !') chiefEnemy = EnemyType('Chief', 'Always behind ... lot of lines.') enemyTypes = {'Soldier' : soldierEnemy, 'Ninja' : ninjaEnemy, 'Chief' : chiefEnemy} enemyCount = {} for i in range(1000000): randomPosX = 0 # random.choice(range(1000)) randomPosY = 0 # random.choice(range(1000)) randomTypeIndex = 0 #random.choice(range(0,len(enemyTypes))) enemyType = enemyTypes.values()[randomTypeIndex] # Here, each enemy only has a reference on its type. enemyList.append(Enemy(randomPosX, randomPosY, enemyType))
Теперь я использую это, чтобы получить мой след памяти (на самых последних строках, прежде чем мое приложение закрывается сама):
import os
import psutil
...
# return the memory usage in MB
process = psutil.Process(os.getpid())
print process.get_memory_info()[0]/float(2 ** 20)
Моя проблема заключается в том, что я не видят никакой разницы между выходом два моих программ:
Оптимизированным = +384,0859375 Mb
Un-оптимизированной = 383.40234375 Mb
Это правильный инструмент для получения памяти? Я новичок в Python, так что это может быть проблемой с моим кодом, но я проверил объекты EnemyType во втором решении, и у меня действительно есть только три события. Поэтому я должен иметь 3 строки девиза вместо 1'000'000.
Я читал об инструменте под названием Heapy для Python, было бы здесь более точным?
Большое спасибо за ваш ответ. Кажется настолько очевидным, что вы сказали это :) Я внес изменения, проверил идентификатор (я не знал, что это было, классно!), И действительно, у меня только 1 идентификатор в моем наборе. Я изменил несколько вещей, и теперь я вижу разницу. Большое спасибо! –