Python、Java和C中的嵌套循环比较

4 投票
6 回答
3022 浏览
提问于 2025-04-16 01:44

下面这段Python代码运行起来非常慢。(我等不及程序结束了,不过我朋友告诉我,他运行这段代码花了20分钟。)

而同样的代码在Java中大约只需要8秒,在C语言中则需要45秒。

我本来就知道Python会慢,但没想到会慢到这个程度。而且我原本以为C语言会比Java快,结果却反而慢了。难道Java虚拟机使用了某种循环展开的技巧来提高速度吗?为什么Python会这么慢呢?

import time
st=time.time()
for i in xrange(0,100000):
    for j in xrange(0,100000):
        continue;
print "Time taken : ",time.time()-st

6 个回答

9

这个教训是:性能永远不是你想象的那样。因此,永远要测量,别轻信。

你可能会看到这些数字的原因有几个(而且根据第一句话,有些可能完全不对):

C语言是为“i586”处理器编译的(也叫做奔腾处理器)。这个CPU从1993年卖到大约2000年。你最近见过这种处理器吗?我想没有吧。所以C代码并没有真正针对你现在的CPU进行优化(换句话说:现在的CPU努力想变得像当年的奔腾CPU一样快)。而Java则是根据你的CPU在加载代码时进行编译的。它可以使用一些C语言无法做到的技巧。代价是,C程序启动只需要15毫秒,而Java程序则需要4秒。

Python目前还没有即时编译器(JIT),所有代码都被转换成字节码,然后再被解释执行。这意味着上面的循环会被转成一堆字节码指令,然后由一个C程序来解释。这就需要时间。Python并不适合处理巨大的循环,它更适合用来实现聪明的算法,而这些算法在其他语言中很难表达(至少在代码量和可读性上无法做到)。

所以,就像用18吨的卡车去购物没有意义(虽然你可以搬运任何东西,但找不到停车的地方),选择编程语言时要根据你需要解决的问题来决定。如果需要小而快?用C。如果只需要快?用Java。如果需要灵活?用Python。如果需要灵活又快:用Python加上一个C语言的辅助库(比如NumPy)。

12

你的测试并没有测量到什么有意义的东西。

一种编程语言在实际使用中的表现,和它执行一个紧凑循环的速度关系不大。

老实说,我对C和Java花了那么长时间感到好奇;我本以为它们的编译器会意识到内层循环里什么都没做,然后把它们优化掉,变成不存在(也就是0秒)。

而Python则是依然在被解释执行(我可能错了)。无论如何,看起来外层循环需要构建100,000个xrange对象来运行那个空的内层循环,这个过程不太可能被优化掉。

所以你真正测量的只是各种编译器识别出没有实际计算工作的能力。

2

使用gcc 4.2编译器,并加上-O1或更高的优化选项,程序会把循环优化掉,这样执行时间只需要1毫秒。这种测试并不能很好地代表实际情况,因为它和真实的使用场景相差很远。你使用嵌套循环是有原因的,而且你不会让它空着。

Python的执行速度比C慢,因为它离机器语言更远。虽然xrange是个不错的抽象,但相比简单的C循环,它增加了很多机器代码的复杂性。

C语言代码:

int main( void ){
        int i, j;
        for (i=0;i<100000;i++){
                for (j=0;j<100000;j++){
                        continue;
                }
        }
        return 0;
}

撰写回答