Rie*_*ess 56 c c++ python performance programming-languages
为什么Python平均比C/C++慢?我学习了Python作为我的第一个编程语言,但我只是从C开始,我已经觉得我可以看到明显的区别.
Mar*_*ers 71
Python是一种比C语言更高级的语言,这意味着它可以从您的内容管理,指针等中抽象出计算机的细节,并允许您以更接近人类思考方式编写程序.
如果只测量执行时间,C代码通常比Python代码快10到100倍.但是,如果您还包括开发时间,Python通常会胜过C.对于许多项目,开发时间远比运行时性能更重要.更长的开发时间可直接转化为额外成本,更少功能和更慢的上市时间.
内部Python代码执行速度较慢的原因是因为代码在运行时被解释而不是在编译时被编译为本机代码.
其他解释性语言(如Java字节码和.NET字节码)运行速度比Python快,因为标准发行版包含一个JIT编译器,可在运行时将字节码编译为本机代码.CPython之所以没有JIT编译器的原因是因为Python的动态特性使得编写它变得困难.有工作的进展情况写一个更快的Python运行,所以你应该期望的性能差距在今后可以减少,但它可能会需要一段时间Python标准版包括一个强大的JIT编译器前.
L̲̳*_*̲̳̳ 42
CPython特别慢,因为它没有Just in Time优化器(因为它是参考实现,并且在某些情况下选择简单性而不是性能).Unladen Swallow是一个将LLVM支持的JIT添加到CPython中的项目,并实现了大规模的加速.Jython和IronPython可能比CPython快得多,并且它们得到了大量优化的虚拟机(JVM和.NET CLR)的支持.
然而,有一件事情可能会让Python变慢,它是动态类型的,并且每个属性访问都有大量的查找.
例如,调用f对象A将导致可能的查找__dict__,调用 __getattr__等,然后最终调用__call__可调用对象f.
关于动态类型,如果您知道要处理的数据类型,可以进行许多优化.例如,在Java或C中,如果您想要求和的直数组,则最终的汇编代码可以像在索引处获取值i,将其添加到accumulator,然后递增一样简单i.
在Python中,很难使代码达到最佳状态.假设您有一个包含ints 的列表子类对象.在添加任何内容之前,Python必须调用list.__getitem__(i),然后通过调用将其添加到"累加器" accumulator.__add__(n),然后重复.这里可以发生大量的替代查找,因为另一个线程可能已经改变了例如__getitem__方法,列表实例的dict或类的dict,在add或getitem的调用之间.即使在本地命名空间中找到累加器和列表(以及您正在使用的任何变量)也会导致dict查找.当使用任何用户定义的对象时,同样的开销也适用,尽管对于某些内置类型,它有所缓解.
值得注意的是,bigint(Python 3中的int,Python 2.x中的long),list,set,dict等原始类型是人们在Python中使用的很多东西.这些对象上有大量内置操作已经足够优化.例如,对于上面的示例,您只需调用sum(list)而不是使用累加器和索引.坚持这些,以及使用int/float/complex进行一些数字运算,你通常不会遇到速度问题,如果你这样做,可能会有一个小的时间关键单元(例如SHA2摘要函数),你可以简单地转到C(或Java代码,在Jython中).事实是,当你编写C或C++代码时,你会浪费很多在几秒钟/几行Python代码中你可以做的事情.我会说这种权衡总是值得的,除非你正在做一些像嵌入式或实时编程这样的东西并且买不起它.
小智 16
编译与解释在这里并不重要:Python 是经过编译的,对于任何非平凡的程序来说,它只是运行成本的一小部分.
主要成本是:缺少对应于本机整数的整数类型(使所有整数运算更加昂贵),缺少静态类型(这使得方法的解决更加困难,并且意味着必须检查值的类型在运行时),并且缺少未装箱的值(这会减少内存使用量,并且可以避免间接级别).
并不是说这些东西中的任何一个都不可能或者不能在Python中更高效,但是已经选择了程序员的方便性和灵活性,以及语言清洁度超过运行时速度.聪明的JIT编译可以克服其中一些成本,但Python提供的好处总是需要付出一些代价.
python和C之间的区别在于解释(字节码)和编译(到本机)语言之间的通常差异.就个人而言,我并不认为python很慢,它管理得很好.如果你试图在它的领域之外使用它,当然,它会更慢.但是为此,你可以为python编写C扩展,它将时间关键算法放在本机代码中,使其更快.
Python 通常作为脚本语言实现。这意味着它通过一个解释器,这意味着它可以将代码即时翻译成机器语言,而不是从一开始就让可执行文件全部使用机器语言。因此,除了执行代码之外,它还必须支付翻译代码的成本。即使对于 CPython 也是如此,即使它编译为更接近机器语言的字节码,因此可以更快地翻译。Python 还带来了一些非常有用的运行时特性,比如动态类型,但即使在没有大量运行时成本的最有效的实现上,这些东西通常也无法实现。
如果您正在执行诸如编写着色器之类的处理器密集型工作,那么 Python 比 C++ 慢 200 倍左右的情况并不少见。如果您使用 CPython,那段时间可以减少一半,但仍然远远不够快。所有这些小东西都是有代价的。有很多基准可以证明这一点,这里有一个特别好的基准。正如首页所承认的,这些基准是有缺陷的。它们都是由用户提交的,他们尽最大努力用他们选择的语言编写高效的代码,但它为您提供了一个很好的总体思路。
如果您关心效率,我建议您尝试将两者混合在一起:这样您就可以两全其美。我主要是一名 C++ 程序员,但我认为很多人倾向于在 C++ 中编写太多普通的高级代码,而这样做很麻烦(编译时间只是一个例子)。将脚本语言与像 C/C++ 这样更接近金属的高效语言混合在一起,确实是平衡程序员效率(生产力)和处理效率的方法。