我有一个对象结构,其中存在相互引用(它的有限元,其中结果需要引用节点和元素,节点和元素需要引用结果(。
我使用weakrefs是为了避免设置永久引用循环来防止垃圾收集。
然而,在分析过程中,我发现清除这些弱点的代价惊人——仅次于scipy的最小化(其性能完全可以理解(。
通过将未使用的weakref表示为None:,我的性能提高了约35%
原件:
def clear_results(self):
self._results = lambda: None # Mimics weakref behaviour, but returns None
速度快35%:
def clear_results(self):
self._results = None # Requires check in the public accessor of self._results
同样是武器的销毁似乎需要时间——武器的创建甚至没有进入分析列表。
这在直觉上似乎不合理——我是不是错过了什么?
我只是想发布这个概要来结束这个问题。几乎所有的信息都来自@MisterMiyagi,我非常感谢他。
简短的回答是"不"——我看到的性能问题并不是由软弱造成的。更重要的是,正如@MisterMiyagi所指出的,它们甚至根本不需要,因为比我开始使用的版本(V1.9(更新的Python版本解决了我使用weakref来防止的问题(https://www.python.org/dev/peps/pep-0442/)。
我能够在两个不相关的问题上提高性能,这可能会引起其他人的兴趣:
-
我的"weakref复制器"(
self._results = lambda: None
(出奇地慢。用自我取代这个_results=没有节省了相当多的时间。 -
我使用了一个listcomp来清除结果:
[item.clear_results() for item in items]
。事实证明,这比直接循环慢得多——部分原因可能是我不需要收集结果。