C ++ vs Java速度(​​带算术的循环)

时间:2017-09-11 19:51:22

标签: java c++ performance loops optimization

以下小程序计算所有数字的总和,从1到10亿,我们用C ++和Java编写,就像我写的那样。我的理解是C ++是更快的"语言,但此代码的java版本在~.5秒内完成,对于C ++,约为3秒。

C ++(GCC编译器):

int main(){
    long long x = 0;
    for (long i=0;i<1000000001;i++){
    x=x+i;
    }
    cout << x << endl;
    return 0;
}

JAVA:

public class Main {
    public static void main(String[] args)  {
        long x=0;
        for (long i=0;i<1000000001;i++){
            x=x+i;
        }
        System.out.println(x);

    }

}

如何优化C ++代码以使其与JAVA版本一样快?它甚至可能吗?

3 个答案:

答案 0 :(得分:5)

如果使用优化进行编译,那么C ++版本相当更快。

Java:

javac Main.java

$ time java Main
500000000500000000

real    0m0.727s
user    0m0.724s
sys     0m0.004s

C ++:

clang -O3 main.cpp -o cpp

$ time ./cpp 
500000000500000000

real    0m0.003s
user    0m0.000s
sys     0m0.000s

我的铿锵版:

$ clang --version
clang version 4.0.0-1ubuntu1 (tags/RELEASE_400/rc1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

我的Java版本:

$ javac -version
javac 1.8.0_144

原因是优化是一个缓慢的过程;如果关闭优化,可以加快编译速度。这对于开发来说更好,所以这是Clang开发人员选择的默认值。 Java可能更快,因为它在运行时进行了更多优化。 JVM字节码 与它编译的源代码不同!

答案 1 :(得分:5)

这个问题是不该做的一个完美的例子。整个循环相当于单个赋值,任何优化编译器都知道它。所以你要测量启动程序和输出一行所需的时间。

然后,Java必须失去你想要的任何因素,因为运行Java代码包括启动JVM并且这很慢。此外,它还包括优化编译。 javac所做的只是从Java源码到Java字节码的编译,并没有尝试优化任何东西。所有优化都在运行时发生(字节码到机器代码)。 1

因此,我们可以得出结论,对于任何花费不到几秒钟的任务,Java非常慢。如果你努力的话,你可以得到20或无穷大的因子(除以零)。

更重要的结论是没有意义。如果您想获得有意义的结果,请参阅How do I write a correct micro-benchmark in Java?

1 这适用于桌面Java。在Android上,它是不同的。

答案 2 :(得分:3)

使用-O选项编译C代码。

在没有-O的情况下生成的程序集包含大量内存访问(慢):

main:
  push rbp
  mov rbp, rsp
  mov QWORD PTR [rbp-8], 0
  mov QWORD PTR [rbp-16], 0
.L3:
  cmp QWORD PTR [rbp-16], 1000000000
  jg .L2
  mov rax, QWORD PTR [rbp-16]
  add QWORD PTR [rbp-8], rax
  add QWORD PTR [rbp-16], 1
  jmp .L3
.L2:

使用-O生成的程序集仅使用寄存器:

main:
  mov eax, 1000000001
.L2:
  sub rax, 1
  jne .L2

请参阅Godbolt的GCC资源管理器输出:https://godbolt.org/g/rx1Va4

编辑:在优化模式下,编译器会识别输出是常量,这就是没有添加指令的原因。请参阅Nathan的示例,其中包含输出:https://godbolt.org/g/r1PxvL