Python 的 weakref 是性能问题吗?

Is Python's weakref a performance issue?

我有一个相互引用的对象结构(它的有限元,结果需要引用节点和元素,节点和元素需要引用结果)。

我正在使用 weakrefs 来避免设置阻止垃圾收集的永久引用循环。

然而,在分析过程中,我发现清除这些 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

这也是 weakref 的破坏 似乎需要时间 - weakref 的创建甚至没有进入分析列表。

这在直觉上似乎不合理 - 我是不是漏掉了什么?

我正准备 post 这个概要来结束这个问题。几乎所有的信息都来自@MisterMiyagi,我的感谢和所有的功劳都归功于他。

简短的回答是 "no" - weakrefs 没有导致我看到的性能问题。更重要的是,正如@MisterMiyagi 指出的那样,它们甚至根本不需要,因为 Python 的最新版本比我开始时 (V1.9) 解决了我使用 weakref 来防止的问题(https://www.python.org/dev/peps/pep-0442/).

我能够在两个不相关的问题上提高性能,其他人可能会对这些问题感兴趣:

  1. 我的 "weakref replicator" (self._results = lambda: None) 出奇地慢。将其替换为 self._results = None 可以节省大量时间。

  2. 我正在使用 listcomp 清除结果:[item.clear_results() for item in items]。事实证明,这比直接循环慢得多 - 部分原因可能是我不需要收集结果。