- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我确实用 Enthought Traits 构建了一个应用程序,它占用了太多内存。我认为,问题是由特征通知引起的:
@on_trait_change 或使用特殊命名约定(例如 _foo_changed() )捕获的事件在内存使用方面似乎存在根本差异。我用两个类 Foo 和 FooDecorator 做了一个小例子,我假设它们表现出完全相同的行为。但他们没有!
from traits.api import *
class Foo(HasTraits):
a = List(Int)
def _a_changed(self):
pass
def _a_items_changed(self):
pass
class FooDecorator(HasTraits):
a = List(Int)
@on_trait_change('a[]')
def bar(self):
pass
if __name__ == '__main__':
n = 100000
c = FooDecorator
a = [c() for i in range(n)]
当使用 c = Foo 运行此脚本时,Windows 任务管理器显示整个 python 进程的内存使用量为 70MB,随着 n 的增加保持不变。对于 c = FooDecorator,python 进程使用 450MB,随着 n 的增加而增加。
你能给我解释一下这种行为吗?
编辑:也许我应该换个说法:为什么有人会选择 FooDecorator 而不是 Foo?
编辑 2:我刚刚卸载了 python(x,y) 2.7.9 并安装了具有 traits 4.5.0 的最新版本的 canopy。现在 450MB 变成了 750MB。
编辑 3:我自己编译了 traits-4.6.0.dev0-py2.7-win-amd64。结果与 EDIT 2 中的结果相同。所以尽管所有合理性 https://github.com/enthought/traits/pull/248/files似乎不是原因。
最佳答案
我相信您看到了最近修复的内存泄漏的影响: https://github.com/enthought/traits/pull/248/files
至于为什么要使用装饰器,在这个特定的例子中,这两个版本实际上是等价的。
一般来说,装饰器更灵活:你可以给出一个要听的特征列表,你可以使用扩展名称表示法,如下所述: http://docs.enthought.com/traits/traits_user_manual/notification.html#semantics
例如,在这种情况下:
class Bar(HasTraits):
b = Str
class FooDecorator(HasTraits):
a = List(Bar)
@on_trait_change('a.b')
def bar(self):
print 'change'
bar
通知程序将被调用以更改特征 a
、它的项以及特征 b
的更改在每个 Bar
项中。扩展名称可能非常强大。
关于python - 内存使用 @on_trait_change 与 _foo_changed(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31682666/
我确实用 Enthought Traits 构建了一个应用程序,它占用了太多内存。我认为,问题是由特征通知引起的: @on_trait_change 或使用特殊命名约定(例如 _foo_changed
我是一名优秀的程序员,十分优秀!