私は Python を学んでおり、パターンの知識を更新する良い言い訳になると思いました。その場合は、Flyweight パターンです。
私は 2 つの小さなプログラムを作成しました。1 つは最適化されておらず、もう 1 つは Flyweight パターンを実装しています。テスト目的で、1'000'000個のEnemy
オブジェクトの軍隊を作成しています。各敵には 3 つのタイプ (ソルジャー、ニンジャ、チーフ) があり、各タイプにモットーを割り当てます。
私が確認したいのは、最適化されていないプログラムを使用すると、1'000'000 の敵が、それぞれのタイプと、モットーを含む「長い」文字列を持つことです。EnemyType
最適化されたコードを使用して、各タイプに一致し、モットーの文字列の 3 倍だけを含むオブジェクト ( ) を 3 つだけ作成したいと思います。Enemy
次に、目的の を指すメンバーを each に追加しますEnemyType
。
コード(抜粋のみ):
最適化されていないプログラム
このバージョンでは、各敵はそのタイプとモットーを保存します。
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
そのタイプとモットーを格納するオブジェクトのメンバーを持っています。の 3 つのインスタンスのみ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)
私の問題は、2 つのプログラムの出力に違いが見られないことです。
最適化 = 384.0859375 Mb
最適化なし = 383.40234375 Mb
メモリフットプリントを取得するための適切なツールですか? 私はPythonを初めて使用するので、コードに問題がある可能性がありますが、2番目のソリューションでEnemyTypeオブジェクトをチェックしましたが、実際には3回しか発生していません。したがって、1'000'000 ではなく 3 つのモットー ストリングを使用する必要があります。
Heapy for Pythonというツールについて読んだことがありますが、こちらの方が正確でしょうか?