【发布时间】:2011-03-10 16:39:02
【问题描述】:
我对 Python 还是很陌生,所以如果这个问题很愚蠢,请原谅我。我无法通过 Google 找到答案...
我在我的代码中使用 PyFFTW,它有一个规划阶段,您可以在其中将两个变量(源/目标)传递给它,这是您从/到的转换。然后,当您调用 FFT 时,它将在计划阶段这些变量所在的确切内存空间上运行。因此,对变量所做的任何操作都需要完成,以便这两个变量在内存中的位置不会改变。
我找到了运算符*=、+= 等,它们对标准数学运算符执行此操作。
但是在我的程序中,我需要对变量应用一个函数,它应该将它返回到相同的内存位置。
怎么办?!
我最初使用切片的方式如下:
a[:] = func(a)[:]
但是我刚刚意识到,这非常慢(我的代码慢了大约 10%)。 那么有人知道该怎么做吗?
非常感谢任何帮助。提前致谢!
【问题讨论】:
-
简而言之,您对 Python 中的内存细节绝对没有权力。甚至切片分配也可以轻松触发重新分配,从而移动项目。一些实现可能会停止世界并压缩整个堆,只是为了在循环中间进行。
-
嗨。我对这个概念感到非常惊讶,因为这会使 PyFFTW 工作方式的想法完全无用,不是吗?!
-
是的,这就是为什么我听到它感到惊讶。如果您坚持使用 CPython(因为 PyFFTW 是一个 C 库,无论如何它都仅限于此)并且不要调整列表的大小,那么您可能会很好。它只是更花哨的垃圾收集器,并且列表超出了已经分配的大小(大多数数据结构都有一点过度分配,所以你可以在重新分配之前有一些项目),这可能会导致令人讨厌的讨厌的问题(来自 segfaults 默默地改变未使用的内存以静默数据损坏)。
-
好的。这非常令人失望,因为我必须寻找一种完全不同的方式来做这件事,因为我的算法实际上是在进行数百万次 FFT 和逆 FFT……整个算法都基于此!
-
一个列表(以及所有其他集合)只分配这么多内存。当您添加更多项目时,您需要重新分配(即从操作系统获取一个新的、完全不相关的内存块并将您的东西复制到那里),因为您无法随心所欲地调整现有内存块的大小。见the source。其他所有语言都存在同样的问题。但是在 C 中,您知道何时重新分配,因为没有人为您进行内存管理。你仍然可以做你想做的事,你只需要事先制作一个适当大小的列表。
标签: python memory variables fftw