Flyweight图案记忆脚垫

2024-09-30 01:23:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我在学习Python,我认为这是一个很好的借口来更新我的模式知识,在这种情况下,Flyweight模式。在

我创建了两个小程序,一个没有优化,另一个正在实现Flyweight模式。为了我的测试目的,我创建了一个1000'000Enemy对象的军队。每一个敌人可以有三种类型(士兵,忍者或首领),我给每一种类型分配一个座右铭。在

我想检查的是,在我未优化的程序中,我有1000万个敌人,每一个都有一个类型和一个包含格言的“长”字符串。 使用优化后的代码,我只想创建三个对象(EnemyType)来匹配每种类型,并且只包含座右铭字符串的3倍。然后,我向每个Enemy添加一个成员,指向所需的EnemyType。在

现在代码(仅摘录):

  1. 未优化程序

    在这个版本中,每一个敌人都有自己的类型和座右铭。在

    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]))
    
  2. 优化程序

    在这个版本中,每个敌人都有一个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
未优化=383.4023475 Mb

它是获得内存占用的合适工具吗?我是Python新手,所以这可能是我的代码有问题,但是我在第二个解决方案中检查了EnemyType对象,我确实只有三次出现。因此我应该有3个座右铭字符串而不是1000'000。在

我读过一篇关于Python的Heapy工具,这里会更准确吗?在


Tags: 对象程序类型rangerandomalwayschoice敌人
1条回答
网友
1楼 · 发布于 2024-09-30 01:23:29

从问题中的代码中我可以看出,在这两种情况下,您只是在为相同的少量实例使用引用。在

以“未优化”版本为例:

enemyList.append(Enemy(randomPosX, randomPosY, enemyType, enemyTypes[enemyType]))

实际上,enemyTypes[enemyType]是一个字符串,这可能会使您认为自己有许多字符串实例。但实际上,每个对象都有一个三个相同的字符串对象。在


您可以通过比较成员的id来检查这一点。做一个set,看看它是否大于3。在

相关问题 更多 >

    热门问题