我最近做了一个类似的测试用一个更现实的现实世界的算法。它涉及numpy、Matlab、FORTRAN和C#(通过ILNumerics).在没有具体优化的情况下,numpy似乎产生的代码效率比其他的低得多。当然--和以往一样--这只能说明一个普遍的趋势。你可以写出FORTRAN代码,最后运行速度比相应的numpy实现慢。但在大多数情况下,numpy会慢得多。这里是我测试的(平均)结果。
为了给你的例子中这种简单的浮点运算计时,所有的一切都归结于编译器生成 "最佳 "机器指令的能力。这里,涉及多少个编译步骤并不重要。.NET和numpy利用了不止一个步骤,首先编译成字节代码,然后在虚拟机中执行。但是优化结果的选项同样存在--在理论上。在实践中,现代FORTRAN和C编译器在优化执行速度方面做得更好。numpy(或更好的CPython,它主要用于numpy)在这一点上似乎表现得更糟。如果你想确保哪个框架最适合你的任务,你可以连接到一个调试器,调查可执行文件的最终机器指令。
然而,请记住,在一个更现实的情况下,浮点性能只在大型优化链的最末端才重要。这种差异往往被一个更强大的影响所掩盖:内存带宽。一旦你开始处理数组(这在大多数科学应用中很常见),你就必须考虑到内存管理的成本。框架在支持算法作者编写内存高效算法方面存在差异。在我看来,numpy比FORTRAN或C语言更难编写内存效率高的算法,但在这些语言中都不容易。(ILNumerics极大地改善了这一点。)
另一个重要的点是并行化。该框架是否支持你并行地执行你的计算?它的效率如何?还是我的个人观点:无论是C语言、FORTRAN语言还是numpy,都不容易使你的算法并行化。但是FORTRAN和C至少给了你这样做的机会,即使它有时需要使用特殊的编译器。其他框架(ILNumerics、Matlab)可以自动并行化。
如果你对非常小但昂贵的算法需要 "峰值性能",你最好使用FORTRAN或C语言,因为它们最终会产生更好的机器代码(在单处理器系统上)。然而,用C语言或FORTRAN语言编写较大的算法和采取内存效率和考虑到并行性往往会变得很麻烦。在这里,高级语言(如numpy、ILNumerics或Matlab)超过了低级语言。如果做得好的话--执行速度的差别往往可以忽略不计。不幸的是,numpy的情况往往不是这样的。