python - 将 python 与 c/fortran 进行比较

标签 python c performance fortran

我编写了以下程序来比较 python 和 c/fortran 的速度。 为了获得程序使用的时间,我使用了“时间”命令。所有 程序计算 xx+yy+z*z 的平方根,其中 x、y、z 是 float 。 我使用了平方根,因为它是最耗时的部分之一 科学计算,我参与其中。

我有以下时间:

fortran  0m29.9s //
c        0m20.7s //
python  30m10.8s

根据我做的简单测试发现Python不推荐用于 科学计算。但可能我的代码效率很低。

您认为我可以仅针对这个简单的测试用例提高我的代码的效率吗?

语言:

program root_square
implicit none

integer i,j
real x,y,z,r

x=1.0
y=2.0
z=3.0

do j=1,3000
    do i=1,1000000
        r=sqrt(x*x+y*y+z*z)
    enddo
enddo

end program root_square

C:

#include "stdio.h"
#include "math.h"

int main (void)
{

float x=1.0,y=2.0,z=3.0,r;
int i,j;

for(j=0; j<3000; j++){
        for(i=0; i<1000000; i++) {
                r=sqrt(x*x+y*y+z*z);
        }
}

return 0;
}

python :

#!/usr/bin/env python

from math import sqrt

x = 1.0
y = 2.0
z = 3.0

for j in range(1,3001):
  for i in range(1,1000001):
    r = sqrt(x*x+y*y+z*z)

最佳答案

我最近做了a similar test使用更现实的现实世界算法。它涉及 numpy、Matlab、FORTRAN 和 C#(来自 ILNumerics)。如果没有特定的优化,numpy 生成的代码似乎比其他代码效率低得多。当然——一如既往——这只能表明一种普遍趋势。您将能够编写最终运行速度比相应的 numpy 实现慢的 FORTRAN 代码。但大多数时候,numpy 会慢得多。这是我测试的(平均)结果:

kmeans comparison results

为了像您的示例中这样简单的浮点运算计时,一切都归结为编译器生成“最佳”机器指令的能力。在这里,涉及多少编译步骤并不重要。 .NET 和 numpy 通过首先编译为字节码然后在虚拟机中执行来利用多个步骤。但优化结果的选项同样存在——理论上。在实践中,现代 FORTRAN 和 C 编译器在优化执行速度方面做得更好。例如,他们利用浮点扩展(SSE、AVX)并进行更好的循环展开。 numpy(或更好的 CPython,主要由 numpy 使用)在这一点上似乎表现更差。如果您想确保哪个框架最适合您的任务,您可以附加调试器并调查可执行文件的最终机器指令。

但是,请记住,在更现实的场景中,浮点性能仅在大型优化链的末端才重要。这种差异通常被更强大的影响所掩盖:内存带宽。一旦你开始处理数组(这在大多数科学应用中很常见),你就必须考虑内存管理的成本。框架在支持算法作者编写内存高效算法方面有所不同。在我看来,numpy 使得编写内存高效算法比 FORTRAN 或 C 更难。但在任何这些语言中都不容易。 (ILNumerics 大大改善了这一点。)

另一个重点是并行化。该框架是否支持您并行执行计算?它的效率如何?还是我个人的观点:C、FORTRAN 和 numpy 都不能轻松地并行化你的算法。但是 FORTRAN 和 C 至少给了你这样做的机会,即使它有时需要使用特殊的编译器。其他框架(ILNumerics、Matlab)会自动并行化。

如果您需要非常小但昂贵的算法的“峰值性能”,您最好使用 FORTRAN 或 C。只是因为它们最终会生成更好的机器代码(在单处理器系统上)。然而,在考虑内存效率并行性的情况下,用 C 或 FORTRAN 编写更大的算法通常会变得很麻烦。在这里,高级语言(如 numpy、ILNumerics 或 Matlab)胜过低级语言。如果做得对 - 执行速度的差异通常可以忽略不计。不幸的是,对于 numpy 的情况通常不是这样。

关于python - 将 python 与 c/fortran 进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9439869/

相关文章:

python - 逻辑回归内存错误

python - 独立应用程序上的 Django ORM

python - 在 Python 中定义强类型变量

c - 使用 sleep 函数时如何增加计数? (C语言)

jQuery 选择器效率

android - findViewById 的效率

.net - 使用 New Relic 监控独立 .NET 桌面应用程序的性能

python - Selenium 在使用 actionchain().move 然后 actionchain.click 或 mouse_up 时挂起

c - 在 C 中使用 drand48_r 作为随机数生成器

c - 如何将字符数组中的每个字符转换为整数?