简单地在python和C ++中运行一个近空的for循环(如下所示),速度非常不同,python慢了一百多倍。
a = 0
for i in xrange(large_const):
a += 1
int a = 0;
for (int i = 0; i < large_const; i++)
a += 1;
另外,我该怎么做才能优化python的速度?
(附: 我在这个问题的第一个版本中做了一个不好的例子,我并不是说a = 1使得C / C ++编译器可以优化它,我的意思是循环本身消耗了大量资源(也许我应该使用+ = 1作为例子)..我的意思是如何优化是如果for循环就像一个+ = 1这么简单,它怎么能以与C / C ++类似的速度运行?在我的实践中,我使用Numpy所以我不能再使用pypy(现在),是否有一些通用的方法可以更快地进行循环(例如生成列表中的生成器)? )
答案 0 :(得分:11)
智能C编译器可以通过识别最后a
总是为1来优化你的循环.Python不能这样做,因为当迭代xrange
时,它需要调用__next__
对象上的xrange
,直到它引发StopIteration
。 python无法知道__next__
是否会产生副作用,直到它调用它为止,因此无法优化循环。本段的内容消息是,优化Python“编译器”而不是C编译器更加困难,因为python是一种动态语言,需要编译器知道对象在某些情况下的行为方式。在
C,这更容易,因为C确切地知道每个对象提前的类型。
当然,除了编译器之外,python还需要做更多的工作。在C
中,您使用硬件说明中支持的操作处理基本类型。在python中,解释器在软件中一次解释一行的字节码。显然,这需要比机器级指令更长的时间。并且数据模型(例如一遍又一遍地调用__next__
)也可以导致许多函数调用,而C不需要这样做。当然,python使用它来使它比编译语言更灵活。
加速python代码的典型方法是使用库或内部函数,它们为低级编译代码提供高级接口。 scipy
和numpy
是这类图书馆的绝佳范例。您可以查看的其他内容是使用包含JIT编译器的pypy
- 您可能无法达到本机速度,但它可能会击败Cpython(最常见的实现),或者在C / fortran中编写扩展使用Cpython-API,cython或f2py作为代码的性能关键部分。
答案 1 :(得分:5)
仅仅因为Python是一种更高级的语言,并且必须在每次迭代时做更多不同的事情(比如获取锁,解析变量等)。
“如何优化”是一个非常模糊的问题。没有“通用”方法来优化任何Python程序(Python的开发人员已经完成了所有可能的工作)。您可以通过以下方式优化您的特定示例:
a = 1
顺便说一下,这就是任何C编译器都会做的。
如果您的程序使用数字数据,那么使用numpy
及其矢量化例程通常会为您提供出色的性能提升,因为它可以完成纯C中的所有操作(使用C循环,而不是Python循环)并且不会必须采取翻译锁和所有这些东西。
答案 2 :(得分:0)
随着你越来越抽象,速度会下降。最快的代码是直接编写的汇编代码。
阅读此问题Why are Python Programs often slower than the Equivalent Program Written in C or C++?
答案 3 :(得分:-1)
Python(通常)是一种解释型语言,这意味着必须在运行时逐行读取脚本,并在此时将其指令编译为可用的字节码。
C(通常)是一种编译语言,所以当你运行它时,你正在使用纯机器代码。
由于这个原因,Python永远不会像C一样快。
编辑:事实上,python在运行时编译INTO C代码,这就是你获取这些.pyc文件的原因。