Python 比 Java/C # 慢吗?

Python 比 Java/C # 慢吗?

Performance- 比较-c-java-python-ruby-jython-jruby-groovy

下面是一个优化 CPython 的项目: 空腹燕子

100565 次浏览

正如注释中建议的那样,您真的应该提供一个测试用例来进行推理。性能差异背后的原因将根据所执行的测试而改变。

然而,我认为静态和动态的本质可能有很大的关系。对于非虚拟调用,JIT 编译的 C #/Java 非常便宜,因为可以在 JIT 时准确地确定它。即使是虚拟调用也只涉及单一级别的重定向。当绑定变得动态时,需要考虑的事情范围更广。

我不知道关于 Python 的足够详细的信息来声称理解其确切的运行时行为,我怀疑这种行为也会因版本和实现的不同而有所不同。有一种叫做“ python 字节码”的东西,然后由一台虚拟机执行——这台虚拟机是否实际执行 JIT 编译就是另一回事了。

我的想法正好相反,我用 Python 写简单程序比用 Java 快, 而且那些 Python 脚本运行得非常快。

当然你的问题没有例子是很难回答的。也许你已经发现了缓慢的库,bug 等等。请给我们更多的细节。

不要把语言和运行时混为一谈。

Python (该语言)有许多运行时实现。

  • CPython 通常是解释型的,比本机代码 C # 要慢。它可能比 Java 慢,这取决于 JavaJIT 编译器。

  • JYthon 在 JVM 中进行解释,并且具有与 Java 相同的性能配置文件。

  • IronPython 与 C # 依赖相同的.NET 库和 IL,因此性能差异相对较小。

  • Python 可以通过 PyREX、 PyToC 等转换为本机代码。在这种情况下,它的性能通常与 C + + 相当。在一定程度上,您可以进一步优化 C + + ,并且可能比 PyREX 未经优化的输出挤出一点更好的性能。

    有关更多信息,请参见 http://arcriley.blogspot.com/2009/03/so-long-pyrex.html

注意,Python (该语言)并不慢。有些 Python 运行时(例如 CPython)会比本机代码 C + + 慢。

问 Python 为什么比 Java/C # 慢是不对的。Java 有多快?天真的解释器比优化的编译器慢十倍左右。我相信有一个用 JavaScript 编写的 Java 字节码解释器-这可能不是很快。因此,这个问题似乎是“为什么 CPython 语言系统比相应的 Sun、 IBM、 Oracle JRE 和 Microsoft 慢。NET 运行时?”

我相信正确答案是非技术性的。最快的 Java 和。NET 运行时更快,因为它们有大量的全职技术团队在性能竞争环境中开发它们。

动态语言系统易于实现。随便哪个白痴都能做到。是的。静态语言系统的设计和实现更加复杂。一个简单的静态系统往往比等效的刚刚工作的动态等效系统运行得快得多。然而,对于高度优化的动态系统来说,运行几乎同样快是可能的。我知道一些 Smalltalk 实现非常好。一个经常被引用的开发动态系统的例子是 MIT Lisp Machine 麻省理工学院 Lisp 机器

此外,如果真正的咕噜声是由库代码完成的,那么语言系统可能就无关紧要了。或者,语言可以鼓励(或给时间(!))开发更有效的算法,可以很容易地消除常数因素的性能差异。

这里有一个用 Python 编写 Java 的清晰例子:

 def __init__(self,size):
self.first = None
last = None
for i in range(size):
current = Person(i)
if self.first == None : self.first = current
if last != None :
last.next = current
current.prev = last
last = current
self.first.prev = last
last.next = self.first

有点像蟒蛇:

 def __init__(self,size):
chain = [Person(i) for i in range(size)]
self.first = chain[0]
chain = zip(chain, chain[1:].append(chain[0]))
for p,n in chain:
p.next = n
n.prev = p

归根结底,编译阶段需要处理的信息较少,因此在使用 Duck 类型(动态类型)语言的情况下,运行时需要做更多的工作。

因此,如果我调用 foo.bar ()方法,在 Java 或 C + + 的情况下,通过发现“ foo”的类型,然后直接调用编译器知道会找到的内存位置的方法,可以在编译过程中优化对 bar 的调用。由于 python 或任何其他动态类型化语言编译器不知道对象 foo 属于什么类型,所以它必须在运行时进行类型检查,然后查找 bar 方法的地址,然后调用它。

除此之外,Python 编译器的编写者还会遇到其他困难,尽管上面的一个问题已经给出了充分的指示。因此,即使使用最好的编译器编写器,静态类型的语言在运行时也可能表现得更好。

其中动态类型语言的得分通常是在开发时间。由于需要编写和维护的代码行较少,而且开发人员没有编译等待时间,因此开发通常会进行得更快。

我认为,编写 Python 代码的简便性使得编写更复杂的代码成为可能; 例如,利用多核处理器的代码。由于在过去的5-10年里,每个核心的性能一直停滞不前,我不认为 Python 程序(无论它们是在 CPython 上运行还是其他程序上运行)从长远来看会变慢。

这与语言本身没有任何关系,只是因为 Java 实施运行时系统(JVM)的质量非常高,而且多年来投入了大量资源用于稳定性、可伸缩性和性能改进。

与之形成对比的是,CPython 实现最近刚刚实现,例如在其解释器中实现了线程分派,这使得它在某些问题上的性能提高了20% 。这并不像听起来那样是件好事,这是件坏事,因为这种基本的优化从一开始就应该存在。

我认为最终 Python 在优化方面并没有走得太远。大多数常用的优化技术都适用于静态语言。对于动态语言,有 优化技术,但是现代的优化技术似乎没有尽可能地利用它们。Steve Yegge 的 关于这个话题的博客文章非常优秀。

编辑 : 我只是想指出,我不一定要说这是对 Python 的批评。比起不必要的速度,我更喜欢简单。

因为它是解释的,而不是编译的. . 所以它的执行时间应该比较慢。

正如 代码完成(第二版)书第600页提到的表格,

C # 在 行刑时间中等于 C + + (1:1) ,而 Python 在 行刑时间中比 C + + 慢100倍以上(> 100:1)。

Java 比 C + + 慢一倍半(1.5:1)。

这些统计数据是平均的,我不知道是谁做的这个研究,但是看起来很有趣。

这种类型的问题不能仅仅通过定性推理来回答,你需要好的基准来支持它。这里有一个比较 Python 3 vs C # Mono的集合,发现 Python 的速度比 Python 3 vs C # Mono慢3到300倍。Python 和 Java 的结果是相似的。(解读基准通常需要谨慎。)

这些基准测试也报告了源代码的大小,Python 比 Java 和 C # 简洁得多。

正如其他答案中提到的,这取决于运行时系统和手头的任务。所以标准的(C) Python 不一定比 Java 或 C # 慢。它的一些模块是用 C 语言实现的,因此结合了 本地人实现和 Python 语言的速度。

我们做了一个小实验: 我们比较了不同语言中 Factorial 计算的执行时间。这个测试实际上是为了评估任意精度整数实现的性能。

testee. language arbitrary-precision integers run-time


1. Java     java.math.BigInteger         JRE 6.13
2. .NET     System.Numerics.BigInteger   MS CLR 4.0
3. Python   long                         Active Python 2.6.2.2
4. Squeak   BigInt                       Squeak 3.10.2
5. .NET     Mono.Math.BigInteger         MS CLR 4.0


results:


1)         2)       3)       4)        5)
10.000!      343 ms    137 ms    91 ms  1.200 ms    169 ms
20.000!    1.480 ms    569 ms   372 ms  1.457 ms    701 ms
30.000!    3.424 ms  1.243 ms   836 ms  3.360 ms  1.675 ms
40.000!    6.340 ms  2.101 ms 1.975 ms  6.738 ms  3.042 ms
50.000!   10.493 ms  3.763 ms 3.658 ms 10.019 ms  5.242 ms
60.000!   15.586 ms  7.683 ms 5.788 ms 14.241 ms 10.000 ms

替换文本 http://www.mycsharp.de/wbb2/attachment.php?attachmentid=6909&sid=0d5aa62b522d005d9e7089785b5d19f1

柱状图显示了结果。巨蟒毫 o 疑是 A 家。据我所知,Python 使用 空手道算法乘以大整数,这解释了速度。

此外,Python 的“任意精度整数”类型是内置的 long。因此,您甚至不需要 Java 的 BigInteger 类所需的特殊类型处理。