为什么python中的琐碎循环比C ++中的慢得多?以及如何优化呢? [英] Why does trivial loop in python run so much slower than the same in C++? And how to optimize that?

查看:152
本文介绍了为什么python中的琐碎循环比C ++中的慢得多?以及如何优化呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只需在python和C ++(如下所示)中运行几乎为空的for循环,速度就大不相同,python慢​​了一百倍.

simply run a near empty for loop in python and in C++ (as following), the speed are very different, the python is more than a hundred times slower.

a = 0
for i in xrange(large_const):
  a += 1

int a = 0;
for (int i = 0; i < large_const; i++)
  a += 1;

另外,我该怎么做才能优化python的速度?

Plus, what can I do to optimize the speed of python?

(添加: 在此问题的第一个版本中,我在这里做了一个不好的例子,我并不是说a = 1以便C/C ++编译器可以优化它,我的意思是循环本身消耗了很多资源(也许我应该使用a +我以"= 1"为例进行说明..我的意思是,如果for循环就像+ = 1一样简单,那么如何以与C/C ++相似的速度运行?在我的实践中,我使用了Numpy,所以现在不再使用pypy,有没有一些通用的方法可以使循环更快得多(例如,生成列表中的generator)? )

(Addition: I made a bad example here in the first version of this question, I don't really mean that a=1 so that C/C++ compiler could optimize that, I mean the loop itself consumed a lot of resource (maybe I should use a+=1 as example).. And what I mean by how to optimize is that if the for loop is just like a += 1 that simple, how could it be run in the similar speed as C/C++? In my practice, I used Numpy so I can't use pypy anymore (for now), is there some general methods for making loop far more quickly (such as generator in generating list)? )

推荐答案

智能C编译器可能会意识到最后a始终为1,从而可以优化循环.Python无法这样做,因为当在xrange上迭代,它需要在xrange对象上调用__next__,直到引发StopIteration. python在调用__next__之前不知道它是否会有副作用,因此无法优化循环.本段的要点是,与C编译器相比,优化Python编译器"是很困难的,因为python是一种动态语言,需要编译器知道对象在某些情况下的行为.在 C,这要容易得多,因为C提前知道每个对象的类型.

A smart C compiler can probably optimize your loop away by recognizing that at the end, a will always be 1. Python can't do that because when iterating over xrange, it needs to call __next__ on the xrange object until it raises StopIteration. python can't know if __next__ will have side-effect until it calls it, so there is no way to optimize the loop away. The take-away message from this paragraph is that it is MUCH HARDER to optimize a Python "compiler" than a C compiler because python is such a dynamic language and requires the compiler to know how the object will behave in certain circumstances. In C, that's much easier because C knows exactly what type every object is ahead of time.

当然,除了编译器外,python还需要做更多的工作.在C中,您正在使用硬件说明中支持的操作来处理基本类型.在python中,解释器在软件中一次解释字节代码.显然,这将比机器级别的指令花费更长的时间.数据模型(例如一遍又一遍地调用__next__)也可能导致很多C不需要做的函数调用.当然,python可以做到这一点,使其比您在编译语言中拥有的灵活性更高.

Of course, compiler aside, python needs to do a lot more work. In C, you're working with base types using operations supported in hardware instructions. In python, the interpreter is interpreting the byte-code one line at a time in software. Clearly that is going to take longer than machine level instructions. And the data model (e.g. calling __next__ over and over again) can also lead to a lot of function calls which the C doesn't need to do. Of course, python does this stuff to make it much more flexible than you can have in a compiled language.

加快python代码速度的典型方法是使用库或内在函数,这些库或内在函数为低级编译代码提供高级接口. scipynumpy是此类库的出色示例.您可以查看的其他内容是使用 pypy ,其中包括JIT编译器-您可能无法达到本机速度,但它可能会击败Cpython(最常见的实现),或者使用Cpython-API,cython或f2py在C/fortran中编写扩展,以提高代码的性能关键部分.

The typical way to speed up python code is to use libraries or intrinsic functions which provide a high level interface to low-level compiled code. scipy and numpy are excellent examples this kind of library. Other things you can look into are using pypy which includes a JIT compiler -- you probably won't reach native speeds, but it'll probably beat Cpython (the most common implementation), or writing extensions in C/fortran using the Cpython-API, cython or f2py for performance critical sections of code.

这篇关于为什么python中的琐碎循环比C ++中的慢得多?以及如何优化呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆