Python比Java/C#慢吗?

75

1
你知道的,你真的应该提供证据来支持这个说法... - annakata
2
为什么要关闭这个问题,我不认为这是主观或争论性的。至少在问题中应该有这么多的灵活性! - Real Red.
2
@annakata:Python 处理数据时可能会比较慢。它的速度明显比 C# 慢。至于 Java,这是有争议的;有很多 JIT 因素会影响它的速度。 - S.Lott
11
Guido有时说:Python注重快速开发,而不是快速运行。您应该能够编写尽可能简单和快速的脚本。 - Michael Piendl
6
"冒犯?!为什么有人把那个问题标记为冒犯?" - vartec
显示剩余11条评论
13个回答

125
不要混淆语言和运行时。
Python(语言)有许多运行时实现。
- CPython通常是解释的,比本机C#慢。根据Java JIT编译器的情况,它可能比Java慢。 - 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++慢。

85
Jython与Java在性能方面完全不同。事实上,在问题所提到的博客文章中,我对它进行了基准测试,结果比Java慢得多。 - Dhananjay Nene
8
这并不是重点——事实是Jython的性能根本无法与Java相提并论。这是由于JVM、语言本身还是在JVM上的实现的原因并不清楚。对我来说,似乎是后者,尤其是因为JRuby似乎与Ruby的C实现具有相同的性能表现。 - Michael Borgwardt
4
通常这是导致问题的原因——但是,“基准测试”如果不符合Python的编程风格,就不能作为比较的标准。在比较C和CPython速度之前,没有人会试图将Python的所有动态内存管理添加到C程序中来证明C更快。 - S.Lott
10
C#和IronPython的运行速度差距很大,这是可以预料的。毕竟,Python是一种更高级别的语言(此外,IronPython编译器也不像C#那样成熟)。 - BlueRaja - Danny Pflughoeft
68
不要将语言与运行时间混淆,但也不要将口头提问与其字面意思混淆。当人们询问这种问题时,他们几乎总是指,“在不需要异常努力或成本的情况下,最快的非奇怪实现与典型运行时环境相结合(这通常意味着相对较新的Windows或Linux系统)是否往往比典型开发更快(“典型”取决于上下文,但通常与通用企业级内容、脚本和/或Web开发有关--仅极少数情况与数值积分有关--由普通开发人员完成)?” - user359996
显示剩余12条评论

62
这并不是正确的问题:为什么Python比Java/C#慢?Java有多快呢?好吧,朴素的解释器比优化后的编译器慢十倍左右。我相信有一种用JavaScript编写的Java字节码解释器 - 那可能不是很快。因此,预期的问题似乎是“为什么CPython语言系统比等效的Sun、IBM和Oracle JRE以及Microsoft .NET运行时慢?”
我认为正确的答案是非技术性的。最快的Java和.NET运行时更快,因为它们有大型全职技术团队在性能竞争环境中开发它们。
动态语言系统易于实现。任何白痴都可以做到。我做过。静态语言系统更复杂,设计和实现起来更复杂。一个简单的静态系统往往会比等效的动态系统运行得更快。然而,高度优化的动态系统也可以运行得几乎一样快。我了解一些Smalltalk实现非常好。一个经常引用的开发动态系统的例子是MIT Lisp Machine
此外,如果真正的grunt工作是由库代码完成的,那么语言系统可能并不重要。或者,该语言可能鼓励(或给时间!)开发更有效的算法,这些算法可以轻松消除常数因子性能差异。

42
我不认为任何白痴都可以做到这一点。这需要一种非常特殊的白痴 :) - Mark Richman

39
作为其他答案中提到的那样,这取决于运行时系统以及手头的任务。因此,标准的(C)Python不一定比Java或C#慢。它的一些模块是用C实现的。因此将本地实现的速度与Python语言相结合。
我们进行了一个小实验:我们比较了不同语言中阶乘计算的执行时间。该测试实际上旨在评估任意精度整数实现的性能。
testee.语言任意精度整数运行时
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
结果:
1) 2) 3) 4) 5) 10,000! 343 毫秒 137 毫秒 91 毫秒 1,200 毫秒 169 毫秒 20,000! 1,480 毫秒 569 毫秒 372 毫秒 1,457 毫秒 701 毫秒 30,000! 3,424 毫秒 1,243 毫秒 836 毫秒 3,360 毫秒 1,675 毫秒 40,000! 6,340 毫秒 2,101 毫秒 1,975 毫秒 6,738 毫秒 3,042 毫秒 50,000! 10,493 毫秒 3,763 毫秒 3,658 毫秒 10,019 毫秒 5,242 毫秒 60,000! 15,586 毫秒 7,683 毫秒 5,788 毫秒 14,241 毫秒 10,000 毫秒

alt text
(来源: mycsharp.de)

这个柱状图显示了结果。Python是明显的赢家。据我所知,Python使用Karatsuba算法来乘以大整数,这解释了速度。

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


1
想一想为什么那些非常聪明的Haskell实现者称其基准套件为NoFib http://www.dcs.gla.ac.uk/fp/software/ghc/nofib.html - igouy
感谢分享这些结果,非常有帮助。 - a.boussema
@wierob 343毫秒 137毫秒 91毫秒 1.200毫秒 169毫秒,这些值是小数吗?0.343 0.137? - 0x12
显示剩余2条评论

31

简单来说,Python很慢

无论你使用哪个解释器(目前可用),它都比Java和C慢。在各种基准测试中,它比Ruby和PHP还要慢。 不要依赖别人的答案,自己检查和验证。

http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=python3&lang2=java&data=u64q

就我个人而言,我认为在使Python更快的问题上并没有做出很多严肃的贡献和开发工作。由于Python的生产力非常高,并且能够直接解决某些问题,因此速度/性能并没有得到严肃对待。还存在一些架构问题,阻碍了Python的性能提升。

免责声明 - 这个答案可能会伤害Python爱好者。我也是Python开发人员,在Django / Flask / Pyramid中开发Web应用程序,而不是Spring(Java)。但是根据我的工作和经验,我看到了Python有多么慢。速度并不总是我的首要考虑因素。但我会支持那些认为Python解释器应该得到润滑和加油或彻底更换引擎,至少能够参加马拉松比赛的人们。它是一种主流编程语言。


14
开发人员的时间更为宝贵。 - Ali Gajani
你能否给出一些架构问题的概述? - oddRaven
2
明显的限制有GIL和单CPU限制。为了进行实验,使用Tornado创建基于Websocket(JSON负载)的实时消息服务器,并尝试测试它可以处理多少连接上的多少条消息。在Golang中编写相同的内容,并获得约xNumCPU的性能。从单进程扩展到多进程(在Tornado Python中)将是开发中的一大步,但在Golang甚至Java中完成会更好(除了Java库问题)。我在这里说的不是理论,而是我们在实践中面临的问题。 - Ravi Kumar

16

如评论中建议的那样,您应该提供一个测试用例来推理。性能差异背后的原因将根据执行的测试而变化。

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

我不知道Python的细节足够多,无法声称理解其精确的运行时行为,我怀疑这也可能随版本和实现的不同而有所变化。有一种名为"python字节码"的东西,然后由虚拟机执行 - 这个虚拟机是否实际上执行JIT编译还是另一回事。


请检查此网址:http://blog.dhananjaynene.com/2008/07/performance-comparison-c-java-python-ruby-jython-jruby-groovy/ - yesraaj
还有一个分支将Python移植到llvm:http://code.google.com/p/unladen-swallow/wiki/ProjectPlan。 - Jason Baker

15

问题在于编译阶段可用的信息较少,因此在动态类型语言中运行时需要更多的工作。这意味着如果我正在进行方法调用foo.bar(),在Java或C++中,通过发现"foo"的类型,可以在编译过程中优化对bar的调用,并直接调用编译器知道将找到的方法的内存位置。由于python或任何其他动态类型语言的编译器不知道foo对象属于哪种类型,因此必须在运行时进行类型检查,然后查找bar方法的地址并执行它。

还有其他困难使python编译器编写者感到苦恼,尽管上面的一个问题希望足够表明情况。因此,即使是最好的编译器编写者,静态类型语言在运行时也很可能表现更好。

动态类型语言的优势通常在于开发时间。由于需要编写和维护的代码行数较少,并且没有开发人员的编译等待时间,因此开发速度通常更快。


2
由于需要编写和维护的代码行数较少,因此Python通常被认为是一种高效的编程语言。然而,随着项目规模的增长,修复Python中的错误变得非常困难。此外,如果人们开始压缩代码,阅读Python代码也往往非常困难。 - Arunav Sanyal

10

你所看到的是使用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  
一种更具Python风格的写法:
 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

9
除非你能提供证据或理由说明“Pythonic”版本会快大约400倍,否则这并不重要。 - Michael Borgwardt
4
指出那些繁琐的低级调整很可能比直接使用Python方式更慢,这点非常相关。然而,在后者中存在一个错误——.append()返回的是None;vartec可能指的是chain[1:]+chain[:1]而不是.append()。 - Alex Martelli
@MichaelBorgwardt 惰性求值的 zip 对于大数组的代码可能会快 400 倍,甚至更多。 - bobrobbob

6
我认为Python无法充分利用优化技术,这主要是因为大多数常见的优化技术都是为静态语言设计的。虽然有一些适用于动态语言的优化技术,但现代技术似乎没有充分利用它们。Steve Yegge在该主题上发布了一篇优秀的博客文章编辑:我只是想指出,我并不是要批评Python。相比无谓的速度,我更喜欢简单易懂。

5

这与编程语言本身无关,只是因为Java的实现JVM(运行时系统)非常高质量,并且多年来已经投入了大量资源来提高稳定性、可扩展性和性能。

相比之下,CPython实现最近才在其解释器中实现了线程分派,从而为某些问题带来了高达20%的性能提升。这并不是好事,因为这种基本的优化应该从一开始就存在。


3

那个链接似乎已经失效了 :-( - starbeamrainbowlabs

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