Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Flyweight图案-内存占用_Python_Python 2.7_Design Patterns_Ubuntu 14.04_Flyweight Pattern - Fatal编程技术网

Python Flyweight图案-内存占用

Python Flyweight图案-内存占用,python,python-2.7,design-patterns,ubuntu-14.04,flyweight-pattern,Python,Python 2.7,Design Patterns,Ubuntu 14.04,Flyweight Pattern,我正在学习Python,我认为这将是一个很好的借口来更新我的模式知识,在这种情况下,Flyweight模式 我创建了两个小程序,一个没有优化,另一个正在实现Flyweight模式。出于测试目的,我正在创建一支由100万敌人对象组成的军队。每个敌人可以分为三种类型(士兵、忍者或首领),我为每种类型指定了一条格言 我想检查的是,通过我未优化的程序,我得到了1'000'000个敌人,每个人都有一个类型和一个包含格言的“长”字符串。 使用优化后的代码,我只想创建三个对象(EnemyType)来匹配每种类

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

我创建了两个小程序,一个没有优化,另一个正在实现Flyweight模式。出于测试目的,我正在创建一支由100万
敌人
对象组成的军队。每个敌人可以分为三种类型(士兵、忍者或首领),我为每种类型指定了一条格言

我想检查的是,通过我未优化的程序,我得到了1'000'000个敌人,每个人都有一个类型和一个包含格言的“长”字符串。 使用优化后的代码,我只想创建三个对象(
EnemyType
)来匹配每种类型,并且只包含座右铭字符串的3倍。然后,我将一个成员添加到每个
敌人
,指向所需的
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
    对象的成员,该对象存储其类型和座右铭。只创建了三个
    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))
    
  • 现在我用它来获取内存占用(在应用程序关闭前的最后几行):

    我的问题是,我看不到我的两个程序的输出之间有任何区别:

    优化=384.0859375 Mb
    未优化=383.40234375 Mb

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


    我已经读过一个名为Python的工具,它在这里会更准确吗?

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

    以“未优化”版本为例:

    enemyList.append(Enemy(randomPosX, randomPosY, enemyType, enemyTypes[enemyType]))
    
    实际上,
    enemyTypes[enemyType]
    是一个字符串,这可能会让您认为您有许多字符串实例。但实际上,每个对象都有三个相同字符串对象中的一个



    您可以通过比较成员的
    id
    s来检查这一点。设置ID的
    集,看看它是否大于3。

    非常感谢您的回答。现在你说的似乎很明显:)我做了更改,检查了id(我不知道它存在,酷!),事实上我在我的集合中只得到了一个id。我改变了一些事情,现在我看到了不同。谢谢你,伙计!
    enemyList.append(Enemy(randomPosX, randomPosY, enemyType, enemyTypes[enemyType]))