Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python与c/fortran的比较_Python_C_Performance_Fortran - Fatal编程技术网

python与c/fortran的比较

python与c/fortran的比较,python,c,performance,fortran,Python,C,Performance,Fortran,我编写了以下程序来比较python与c/fortran的速度。 为了获得程序使用的时间,我使用了“time”命令。所有的 程序计算xx+yy+z*z的平方根,其中x,y,z是浮点数。 我使用了平方根,因为它是计算机中最耗时的部分之一 科学计算,我参与其中 我得到了以下几次: fortran 0m29.9s // c 0m20.7s // python 30m10.8s 根据我做的简单测试,我发现Python不推荐用于 科学计算。但我的代码可能效率很低 您认为我是否可以仅针对这

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

我得到了以下几次:

fortran  0m29.9s //
c        0m20.7s //
python  30m10.8s
根据我做的简单测试,我发现Python不推荐用于 科学计算。但我的代码可能效率很低

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

Fortran:

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:


您没有确切地解释度量的目标是什么,因此很难回答您的测试代码是否能够充分地为您提供满足该目标的信息。一般来说,基准测试的存在是为了告诉你一些非常具体的事情——通过执行基准测试,你应该确切地知道你想要弄明白什么。你在上面尝试的那种微基准也因提供扭曲的答案而臭名昭著……

通常,numpy用于python中的科学计算。您可能应该测试该库。

您可能可以。 python有许多数学库,它们可能可以更高效地完成您想要的任务。
由于python范围的工作方式与c循环完全不同,我将首先尝试展开这些循环。

请注意,
r
的计算不依赖于循环变量,因此优化编译器可能会将计算移出循环,只需按要求的次数运行空循环;甚至完全删除该循环,只计算平方根。

一个真正聪明的优化器可能会注意到你没有对结果做任何事情,因此整个程序可能会在不改变输出的情况下被优化掉(即没有任何结果)。

在你开始比较这样的计时之前,有许多事情你应该注意

  • 正如在另一个答案中提到的,可能是编译器优化了循环和实际值。此外,即使打印结果,也可以预先计算平方根
  • 您在Fortran中使用的是
    real
    ,在C中使用的是
    float
    ,因此(当然取决于您的系统),编译器可能会在Fortran中使用
    sqrtf
    库调用,而在C中使用的是
    sqrt
    而不是
    sqrtf
    ,后者应该用于
    float
  • 在Python中,您应该使用和包,它们提供数组,您可以在这些数组上执行有效的整个数组操作,从而避免Python中的循环
  • 有缺陷的基准

    如果您想对浮点运算计时,那么您应该首先对循环计时,不做任何事情(或者尽可能接近于不做任何事情)。为了避免优化整个循环,请确保它执行类似于将单字节字符从一个数组移动到另一个数组的操作

    然后用浮点计算再次计时,并减去第一个计时,以获得更准确的数字


    此外,Python只有双浮点数,因此更均匀的测试将确保其他语言也使用浮点数。正如其他人所提到的,Python广泛用于科学计算,但这些科学家通常使用numpy库进行矩阵计算,而不是编写Python循环。

    对于计算,我可以尝试haskell或ml

    在ML中尝试此代码:

    fun trip(x,y,z) = if y=z then 0
        else trip(((Math.sqrt((1.0*1.0)+(2.0*2.0)+(3.0*3.0)))*1.0),(y+1),z);
    trip(1.0,1,300000000);
    
    我最近用了一种更真实的算法。它包括numpy、Matlab、FORTRAN和C#(via)。如果没有特定的优化,numpy生成的代码效率似乎比其他代码低得多。当然,一如既往,这只能说明一种普遍趋势。您将能够编写FORTRAN代码,其最终运行速度将低于相应的numpy实现。但大多数时候,numpy的速度会慢得多。这里是我测试的(平均)结果:

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

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

    另一个要点是并行化。框架是否支持您并行执行计算?它的效率如何?再次重申我的个人观点:无论是C、FORTRAN还是numpy都不能使并行化算法变得容易。但是FORTRAN和C至少给了您这样做的机会,即使有时需要使用特殊的编译器。其他框架(IL)
    #!/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)
    
    fun trip(x,y,z) = if y=z then 0
        else trip(((Math.sqrt((1.0*1.0)+(2.0*2.0)+(3.0*3.0)))*1.0),(y+1),z);
    trip(1.0,1,300000000);