在大型阵列上执行更快的手动操作?

2024-09-30 06:34:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些代码最初是用C编写的(由其他人使用C风格的malloc数组编写的)。后来我将它转换成C++风格,使用^ {CD1}}数组与项目的其余部分保持一致性。我从来没有计时,但两种方法似乎速度相似。在

我最近用python启动了一个新项目,我想使用一些旧代码。由于不想在项目之间来回移动数据,我决定将这些旧代码移植到python中,这样就可以在一个项目中完成所有的工作。我天真地用python语法键入所有代码,用numpy数组替换旧代码中的任何数组(将它们初始化为array = np.zeros(list((1024, 1024)), dtype=complex))。这段代码运行得很好,但速度非常慢。如果非要我猜的话,我会说它大约慢了1000倍。在

现在经过调查,我发现很多人都说numpy对于元素操作来说非常慢。虽然我已经将一些numpy函数用于常见的数学运算,例如fft和矩阵乘法,但我的大部分代码都涉及嵌套for循环。其中很多都是相当复杂的,在我看来不适合简化为在numpy中更快的简单数组操作。在

所以,我想知道是否有一种方法可以代替numpy更快地进行这种计算。理想的情况是,我可以导入一个具有许多相同功能的模块,因此我不必重写太多代码(例如,可以以相同的方式执行fft和初始化数组等),但是如果不能这样做,我会很高兴至少能用在更高计算要求上的东西部分代码,并根据需要在numpy数组之间来回转换。在

cpython数组听起来很有前途,但是我看到的许多基准测试在速度上并没有表现出足够的差异。为了让大家了解我所说的这类事情,这是减慢代码速度的方法之一。这被调用数百万次,vz_at()方法包含一个查找表,并进行一些插值以给出最终返回值:

    def tra(self, tr, x, y, z_number, i, scalex, idx, rmax2, rminsq):
        M = 1024
        ixo = int(x[i] / scalex)
        iyo = int(y[i] / scalex)
        nx1 = ixo - idx
        nx2 = ixo + idx
        ny1 = iyo - idx
        ny2 = iyo + idx

        for ix in range(nx1, nx2 + 1):
            rx2 = x[i] - float(ix) * scalex
            rx2 = rx2 * rx2
            ixw = ix
            while ixw < 0:
                ixw = ixw + M
            ixw = ixw % M
            for iy in range(ny1, ny2 + 1):
                rsq = y[i] - float(iy) * scalex
                rsq = rx2 + rsq * rsq
                if rsq <= rmax2:
                    iyw = iy
                    while iyw < 0:
                        iyw = iyw + M
                    iyw = iyw % M
                    if rsq < rminsq:
                        rsq = rminsq
                    vz = P.vz_at(z_number[i], rsq)
                    tr[ixw, iyw] += vz

总之,有几千行代码;这只是一个小片段来举个例子。明确地说,我的很多数组都是1024x1024x1024或1024x1024,并且值很复杂。其他的是一百万个元素的一维数组。我能加速这些元素操作的最好方法是什么?在


Tags: 项目方法代码numpy元素for数组速度
1条回答
网友
1楼 · 发布于 2024-09-30 06:34:05

对于信息,您的一些代码可以变得更简洁,从而更具可读性。例如:

array = np.zeros(list((1024, 1024)), dtype=complex)).

可以写

^{pr2}$

当您尝试Python时,这至少是一个不错的好处:-)

现在,对于您的问题,在当前的Python科学领域有几种解决方案:

  1. Numba是一个针对Python的实时编译器,专门用于数组处理,在NumPy达到极限时可以获得良好的性能。在

    优点:只需编写纯Python,对代码几乎没有修改,在许多情况下都表现出良好的性能。Numba应该识别一些NumPy操作,以避免Numba->;Python->;NumPy减速。
    缺点:安装和分发基于Numba的代码可能很麻烦。

  2. Cython是Python和C的混合,用于生成编译函数。您可以从纯Python文件开始,通过类型注释和使用一些“C”ism来加速代码。在

    优点:稳定,广泛使用,相对容易分发基于Cython的代码。
    缺点:需要重写性能关键的代码,即使只是部分重写。

另一个提示是,nicolasrougier(法国科学家)写了一本在线书籍,介绍了许多可以使用NumPy加速Python代码的情况:http://www.labri.fr/perso/nrougier/from-python-to-numpy/

相关问题 更多 >

    热门问题