为什么python中的平凡循环比c++中的要慢得多?以及如何优化它
Why does trivial loop in python run so much slower than the same in C++? And how to optimize that?
简单地在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++编译器可以优化它,我的意思是循环本身消耗了很多资源(也许我应该使用a+=1作为例子)..我说如何优化的意思是,如果for循环就像a += 1那么简单,它怎么能以C/c++的速度运行呢?在我的实践中,我使用Numpy,所以我不能再使用pypy了(现在),有没有一些通用的方法可以更快地创建循环(比如生成器在生成列表)?)
一个聪明的C编译器可能会通过识别到最后,a
总是为1来优化你的循环。Python不能这样做,因为当迭代xrange
时,它需要在xrange
对象上调用__next__
,直到引发StopIteration
。python在调用__next__
之前无法知道它是否有副作用,所以没有办法优化循环。这段话的要点是,优化Python"编译器"比C编译器要困难得多,因为Python是一种动态语言,需要编译器知道对象在特定情况下的行为。在在C语言中,这要容易得多,因为C语言提前知道每个对象的确切类型。
C
中,您使用硬件指令中支持的操作来处理基类型。在python中,解释器一次一行地解释software中的字节码。显然,这将比机器级指令花费更长的时间。数据模型(例如,一遍又一遍地调用__next__
)也会导致很多C不需要做的函数调用。当然,python做这些事情是为了使它比编译语言更灵活。
加速python代码的典型方法是使用库或内部函数,它们为低级编译代码提供高级接口。scipy
和numpy
是这类库的很好的例子。你可以考虑的其他事情是使用pypy
,它包含一个JIT编译器——你可能不会达到原生速度,但它可能会超过Cpython(最常见的实现),或者使用Cpython- api在C/fortran中编写扩展,cython或f2py用于代码的性能关键部分。
原因很简单,因为Python是一种更高级的语言,每次迭代都要做更多不同的事情(比如获取锁,解析变量等)
"如何优化"是一个非常模糊的问题。没有"通用"的方法来优化任何Python程序(Python的开发人员已经做了所有可能的事情)。您的特定示例可以这样优化:
a = 1
这是任何C编译器都会做的,顺便说一下
如果你的程序处理数值数据,那么使用numpy
和它的矢量化例程通常会给你带来很大的性能提升,因为它用纯C(使用C循环,而不是Python循环)完成所有工作,并且不需要使用解释器锁和所有这些东西。
Python(通常)是一种解释性语言,这意味着必须在运行时逐行读取脚本,并在此时将其指令编译成可用的字节码。
C(通常)是一种编译语言,所以当你运行它的时候,你正在处理纯机器码。
Python永远不会像C一样快,因为这个原因。
编辑:事实上,python在运行时编译成C代码,这就是为什么你得到那些。pyc文件。
越抽象,速度越慢。最快的代码是直接编写的汇编代码。
阅读这个问题为什么Python程序通常比用C或c++编写的等效程序慢?
- 空基优化子对象的地址
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 返回值优化:显式移动还是隐式
- 人脸跟踪arduino代码的优化
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 纯函数,为什么没有优化
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 如何以优化的方式同时迭代两个间距不相等的数组
- 小字符串优化(调试与发布模式)
- 浮点定向舍入和优化
- Visual Studio 调试优化如何工作?
- 为什么开关的优化方式与 c/c++ 中的链接不同?
- 线性优化目标函数中的绝对值
- GCC 会优化内联访问器吗?
- gcc 如何优化此循环?
- 如何防止 CUDA-GDB 中的<优化输出>值
- 为什么我的程序在 O0 和 O2 的优化级别返回不同的结果
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 使用 std::p air 进行返回值优化