java - 为什么 Java 在这里运行得比 C 快?

标签 java c performance

灵感来自 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 位

编辑

这太棒了。在 C 中使用 -O3 选项优化循环并在 Java 中使用 -server 做同样的事情。这是“优化时间”。 optimized

最佳答案

我预计 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/

相关文章:

Java小程序白屏

java - 在java中获取文件扩展名

c - 如何修复 "implicit declaration of function"

javascript - 高效的 Javascript 字符串替换

java - 初始容量如何影响 HashMap 的性能

java - Spring框架中的DAO和Service层到底是什么?

javascript - HTMLUnit 不等待 JavaScript

c - C中的限定符和说明符有什么区别?

c++ - Malloc 或 Calloc 以及何时

android - Ionic 2 安卓性能