10

我正在将 C++ 科学应用程序移植到 python,由于我是 python 新手,我想到了一些问题:

1)我正在定义一个包含坐标(x,y)的类。这些值将被多次访问,但它们只会在类实例化之后被读取。在内存和访问时间方面使用元组还是 numpy 数组更好?

2) 在某些情况下,这些坐标将用于构建复数,在复函数上求值,并且将使用该函数的实部。假设没有办法将这个函数的实部和复数分开,并且最后必须使用实部,也许直接使用复数来存储(x,y)更好?在 python 中从复杂到真实的转换的开销有多严重?c++ 中的代码做了很多这样的转换,这是该代码的一个很大的减速。

3) 还必须执行一些坐标变换,对于坐标,x 和 y 值将分别访问,完成变换并返回结果。坐标变换是在复平面上定义的,所以直接使用分量 x 和 y 比依赖复变量更快吗?

谢谢

4

2 回答 2

7

在内存消耗方面,numpy 数组比 Python 元组更紧凑。numpy 数组使用单个连续的内存块。numpy 数组的所有元素都必须是声明类型(例如 32 位或 64 位浮点数)。Python 元组不一定使用连续的内存块,元组的元素可以是任意 Python 对象,这通常比 numpy 数字类型消耗更多的内存。

所以这个问题对于 numpy 来说是一个不折不扣的胜利,(假设数组的元素可以存储为 numpy 数字类型)。

关于速度问题,我认为选择归结为一个问题,“你能矢量化你的代码吗?”

也就是说,您能否将您的计算表达为对整个数组元素进行的操作。

如果代码可以向量化,那么 numpy 很可能会比 Python 元组更快。(我能想象到的唯一情况是,如果你有许多非常小的元组。在这种情况下,形成 numpy 数组的开销和导入 numpy 的一次性成本可能会淹没矢量化的好处。)

无法向量化的代码示例是,如果您的计算涉及查看,例如,数组中的第一个复数z,进行生成整数索引的计算idx,然后检索z[idx],对该数字进行计算,生成next index idx2,然后 retrievingz[idx2]等。这种类型的计算可能无法矢量化。在这种情况下,您不妨使用 Python 元组,因为您将无法利用 numpy 的优势。

我不会担心访问复数的实部/虚部的速度。我的猜测是矢量化问题很可能决定哪种方法更快。(不过,顺便说一句,numpy 可以将复数数组转换为实数部分,只需跨过复数数组,跳过每隔一个浮点数,并将结果视为浮点数。此外,语法非常简单:如果z是复杂的 numpy 数组,然后z.real是浮点 numpy 数组的实部。这应该比使用属性查找的列表理解的纯 Python 方法快得多:[z.real for z in zlist]。)

只是出于好奇,您将 C++ 代码移植到 Python 的原因是什么?

于 2010-04-02T03:37:33.643 回答
3

A numpy array with an extra dimension is tighter in memory use, and at least as fast!, as a numpy array of tuples; complex numbers are at least as good or even better, including for your third question. BTW, you may have noticed that -- while questions asked later than yours were getting answers aplenty -- your was laying fallow: part of the reason is no doubt that asking three questions within a question turns responders off. Why not just ask one question per question? It's not as if you get charged for questions or anything, you know...!-)

于 2010-04-02T02:50:41.020 回答