NumPy和SciPy中有多少是用C语言编写的?

28

NumPy和/或SciPy的部分代码是用C/C++编写的吗?

从Python调用C函数的开销与从Java和/或C#调用C函数的开销相比如何?

我只是想知道,对于科学应用程序,Python是否比Java或C#更好。

如果我看一下shootouts,Python输了很多。但我想这是因为在这些基准测试中没有使用第三方库。


2
不要忘记Fortran。Python也可以很好地与Fortran配合使用。 - John La Rooy
@~unutbu 有点令人困惑,您为什么期望regex-dna程序使用numpy。 - igouy
如果您仔细查看,会发现还有一个“有趣的替代品” Python 程序,它确实使用了 Numpy。http://shootout.alioth.debian.org/u32/benchmark.php?test=spectralnorm&lang=python&id=2 - igouy
5个回答

19
  1. 我会对任何没有显示每个实现源代码的基准测试提出质疑(或者我错过了什么)?这完全有可能是其中一个或两个解决方案编码不良,导致对其中一个或两个语言的表现偏颇。 [编辑] 哦,现在我看到源代码了。正如其他人所指出的那样,它没有使用NumPy/SciPy库,因此这些基准测试将无法帮助您做出决策。
  2. 我相信绝大部分NumPy和SciPy是用C语言编写的,并在Python中进行包装以便于使用。
  3. 对于任何语言,特定应用程序的开销都取决于您要做什么。

我已经使用Python处理和分析数据有几年了,所以我可以说它肯定是能胜任的。

最终你想要达到什么目标呢?如果您想快速开发可读性强的代码,Python是一个很好的选择,并且对于您尝试解决的问题的第一次尝试来说足够快。

为什么不针对问题的一个小子集尝试每种语言,并根据开发时间和运行时间对结果进行基准测试?然后,您可以根据一些相关数据做出客观决策...或者至少这就是我会做的 :-)


源代码可通过导航到特定程序来获取。向下滚动到底部,然后单击其中一个“Python CPython”链接。例如:http://shootout.alioth.debian.org/u32/benchmark.php?test=mandelbrot&lang=python&id=5 - user93202
1
目前为止,我下载了NumPy源代码,可以确认它主要是用Python封装的C语言编写的。 - user93202
“for now” 意思是如果没有人提供 Python、Java 和 C# 中 C 互操作性的不同成本比较,那么这是一个很好的答案,我会接受它。此外,我会遵循您的建议,在这三种语言中原型化应用程序的一部分。 - user93202
请在顶部加上 [编辑],以便每个人都能看到您的错误。出于好奇,您是否查看了更多页面而不仅仅是被引用的那一页?或者我错过了什么? - igouy

8

这里有一个更好的比较(不是基准测试,而是展示了加速Python的方法)。NumPy大部分是用C语言编写的。Python的主要优势在于有多种方法可以非常容易地使用C(ctypes、swig、f2py)/ C++(boost.python、weave.inline、weave.blitz)/ Fortran(f2py)扩展您的代码 - 或者只需添加类型注释到Python中,使其可以被转换为C(cython)。我认为对于C#或Java来说,很少有东西能像Python那样轻松处理传递不同类型的数字数组(尽管我猜支持者会争辩说由于它们没有Python的性能惩罚,因此需要较少)。


1
你的链接似乎已经失效了,也许你可以更换一下? - Robin Ellerkmann
无缝断链 - vwvan

5

NumPy的大部分代码都是用C语言编写的,但其中很大一部分C代码只是为了处理Python/C接口的所有细节而进行的“样板”编写。我认为NumPy中C语言和Python语言的比例大约是50/50。

我对基于虚拟机的低级细节不太熟悉,但我相信由于jvm和.clr上的限制,接口成本会更高。NumPy通常比类似环境更快的原因之一是存储器表示以及如何在函数之间共享/传递数组。而大多数环境(我相信Matlab和R也是如此)使用Copy-On-Write来在函数之间传递数组,而NumPy使用引用。但在例如JVM中这样做会很困难(因为限制如何使用指针等)。这是可以做到的(Jython的一个早期版本已经移植了NumPy),但我不知道他们是如何解决这个问题的。也许C++/Cli会使这更容易,但我对那个环境毫无经验。


@DavidCournapeaud,从C#向本地dll传递数组就像传递指针一样容易。实际上,不会像Java那样复制数组。该数组作为(固定)引用传递,开销非常小。 - user492238
@DavidCournapeaud 请提供JVM和CLR有限制的参考资料。我开发过Python和Java(以及其他语言)的科学软件,没有遇到这样的问题,也没有比NumPy慢。实际上,情况似乎相反,因为例如线性代数库在任何体面的库中都是本地优化代码,并且在大多数编译语言中处理本机数字计算之外的数据(循环,条件等)归结为C性能(或许多语言,而不仅仅是Python)。 - dawid

5

很多IT技术都是用C或Fortran编写的。你可以用C重写热循环(或使用众多加速Python的方法,Boost/Weave是我最喜欢的),但这真的很重要吗?

科学应用程序只需要运行一次。其余的只是调试和开发,而在Python上这些可以更快速。


1
真的 - 你应该试一下:使用Python Numeric从Python交互式控制台创建一些矩阵,并对它们进行一些“实时”操作。-- 它为您提供了无与伦比的易用性和灵活性,这在其他工具中是无法超越的 - 这加快了任何开发速度,因为可以立即尝试新的想法和使用模式。SciPy交互提示通常用作MatLab和其他昂贵(且有些受限)科学工具的替代品。 - jsbueno
2
你的科学应用程序只需要运行一次。其余的工作都是调试和开发,而这些在 Python 上可以更快地完成。——通常我会同意这个观点。但是这个应用程序可能需要运行数天甚至数周,因此稍微缩短一点处理时间就能节省大量实际时间。它将被运行多次。 - user93202

0

这完全取决于你自己处理语言的能力,因此语言能够生成快速的代码。根据我的经验,numpy比好的.NET实现要慢几倍。我预计JAVA也会非常快。他们的优化JIT编译器在多年来已经显著改进,并产生非常高效的指令。

另一方面,numpy具有更易于使用的语法,适用于那些熟悉脚本语言的人。但是,如果涉及应用程序开发,这些优势通常会变成障碍,您将渴望类型安全和企业IDE。此外,C#的语法差距正在缩小。越来越多的科学库存在于Java.NET中。个人倾向于C#,因为它提供了更好的多维数组语法,并且在某种程度上感觉更加“现代”。但当然,这只是我的个人经验。


包括一个简单的基准测试将更精确地证明这个立场。 - vwvan
1
@vwvan,您想看到哪部分/语句通过基准测试来支持呢?“慢几倍”?“感觉更现代化”?我已经强调了我的回答是主观的。对于一个无法客观回答的问题,对主观回答进行负评价,这至少让您的动机受到质疑。在我看来。 - user492238
1
我也这么认为。回到中立值,因为这是一个好答案。 - ElDoRado1239

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接