灵感来自 this question ,
现在仅对拥有 > 10k 代表的用户可见
我想出了以下代码:
$cat loop.c
int main( int argc, char ** argv )
{
int i = 0;
while( i++ < 2147483647 );
}
$cc -o loop loop.c
$ time ./loop
real 0m11.161s
user 0m10.393s
sys 0m0.012s
$cat Loop.java
class Loop {
public static void main( String [] args ) {
int i = 0;
while( i++ < 2147483647 );
}
}
$javac Loop.java
$time java Loop
real 0m4.578s
user 0m3.980s
sys 0m0.048s
为什么 Java 版本的运行速度几乎比 C 版本快 3 倍?我在这里缺少什么?
这是在 Ubuntu 9.04 上运行的:
英特尔(R) 奔腾(R) M @ 1.73GHz
32 位
编辑
最佳答案
我预计 javac
的默认优化级别高于您的 C 编译器。当我在这里用 -O3
编译时,C 的速度更快:
C 与 -O3
:
real 0m0.003s
user 0m0.000s
sys 0m0.002s
你的java程序:
real 0m0.294s
user 0m0.269s
sys 0m0.051s
更多细节;没有优化,C 编译为:
0000000100000f18 pushq %rbp
0000000100000f19 movq %rsp,%rbp
0000000100000f1c movl %edi,0xec(%rbp)
0000000100000f1f movq %rsi,0xe0(%rbp)
0000000100000f23 movl $0x00000000,0xfc(%rbp)
0000000100000f2a incl 0xfc(%rbp)
0000000100000f2d movl $0x80000000,%eax
0000000100000f32 cmpl %eax,0xfc(%rbp)
0000000100000f35 jne 0x00000f2a
0000000100000f37 movl $0x00000000,%eax
0000000100000f3c leave
0000000100000f3d ret
经过优化(-O3
),它看起来像这样:
0000000100000f30 pushq %rbp
0000000100000f31 movq %rsp,%rbp
0000000100000f34 xorl %eax,%eax
0000000100000f36 leave
0000000100000f37 ret
如您所见,整个循环已被删除。 javap -c Loop
为我提供了 java 字节码的输出:
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: ldc #2; //int 2147483647
8: if_icmpge 14
11: goto 2
14: return
}
看来循环是编译进去的,我猜想在运行时会发生一些事情来加快循环速度。 (正如其他人所提到的,JIT 编译器压缩了循环。)
关于java - 为什么 Java 在这里运行得比 C 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2260157/