为什么这个简单的 C++ 加法比等效的 Java 慢 6 倍? [英] why is this simple C++ addition 6 times slower than the equivalent Java?

查看:71
本文介绍了为什么这个简单的 C++ 加法比等效的 Java 慢 6 倍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好stackoverflow用户,这是我问的第一个问题,所以如果我的表达方式有任何错误,请指出,谢谢

hello stackoverflow users, this is my first question asked, so if there are any errors in my way of expressing it, please point it out, thank you

我用 Java 和 C++ 编写了这个简单的计算函数

I wrote this simple calculation function in both Java and C++

Java:

long start = System.nanoTime();
long total = 0;
for (int i = 0; i < 2147483647; i++) {
    total += i;
}
System.out.println(total);
System.out.println(System.nanoTime() - start);

C++:

auto start = chrono::high_resolution_clock::now();
register long long total = 0;
for (register int i = 0; i < 2147483647; i++)
{
    total += i;
}
cout << total << endl;
auto finish = chrono::high_resolution_clock::now();
cout << chrono::duration_cast<chrono::nanoseconds>(finish - start).count() << endl;

软件:- JDK8u11- Microsoft Visual C++ 编译器 (2013)

software: - JDK8u11 - Microsoft Visual C++ Compiler (2013)

结果:

Java:23058430059924684811096361110

Java: 2305843005992468481 1096361110

C++:23058430059924684816544374300

C++: 2305843005992468481 6544374300

计算结果是一样的,这很好然而,打印的纳米时间显示 Java 程序需要 1 秒,而在 C++ 中执行需要 6 秒

The calculation results are the same, which is good however, the nano time printed shows the Java program takes 1 second while in C++ it takes 6 seconds to execute

我已经使用 Java 有一段时间了,但我是 C++ 新手,我的代码有问题吗?还是说 C++ 在计算简单的情况下比 Java 慢?

I've been doing Java for quite some time, but I am new to C++, is there any problem in my code? or is it a fact that C++ is slower than Java with simple calculations?

另外,我在我的 C++ 代码中使用了register"关键字,希望它能带来性能提升,但执行时间根本没有区别,有人可以解释一下吗?

also, i used the "register" keyword in my C++ code, hoping it will bring performance improvements, but the execution time doesn't differ at all, could someone explain this?

我这里的错误是C++编译器设置没有优化,输出设置为x32,应用/O2 WIN64并删除DEBUG后,程序只用了0.7秒执行

My mistake here is the C++ compiler settings are not optimized, and output is set to x32, after applying /O2 WIN64 and removing DEBUG, the program only took 0.7 seconds to execute

JDK默认对输出进行优化,而VC++不是这样,默认情况下它有利于编译速度,不同的C++编译器的结果也不同,有些会在编译时计算循环的结果,导致极短执行时间(大约 5 微秒)

The JDK by default applies optimization to output, however this is not the case for VC++, which favors compilation speed by default, different C++ compilers also vary in result, some will calculate the loop's result in compile time, leading to extremely short execution times (around 5 microseconds)

注意:在合适的条件下,C++ 程序在这个简单的测试中将比 Java 执行得更好,但是我注意到许多运行时安全检查被跳过,违反了它作为安全语言"的调试意图,我相信 C++ 会更多在大型数组测试中优于 Java,因为它没有边界检查

NOTE: Given the right conditions, the C++ program will perform better than Java in this simple test, however I noticed many runtime safety checks are skipped, violating it's debug intention as a "safe language", I believe C++ will even more outperform Java in a large array test, as it does not have bound checking

推荐答案

在 Linux/Debian/Sid/x86-64 上,使用 OpenJDK 7 和

On Linux/Debian/Sid/x86-64, using OpenJDK 7 with

// file test.java
class Test {
    public static void main(String[] args) {
    long start = System.nanoTime();
    long total = 0;
    for (int i = 0; i < 2147483647; i++) {
        total += i;
    }
    System.out.println(total);
    System.out.println(System.nanoTime() - start);
    }
}   

和 GCC 4.9 与

and GCC 4.9 with

   // file test.cc
#include <iostream>
#include <chrono>

int main (int argc, char**argv) {
 using namespace std;
 auto start = chrono::high_resolution_clock::now();
 long long total = 0;
 for (int i = 0; i < 2147483647; i++)
   {
     total += i;
   }
 cout << total << endl;
 auto finish = chrono::high_resolution_clock::now();
 cout << chrono::duration_cast<chrono::nanoseconds>(finish - start).count()
      << endl;
}    

然后用

javac test.java
java Test

我正在获取输出

2305843005992468481
774937152

在编译 test.cc 时进行优化

g++ -O2 -std=c++11 test.cc -o test-gcc

并运行 ./test-gcc 它会更快

2305843005992468481
40291

当然没有优化g++ -std=c++11 test.cc -o test-gcc运行比较慢

Of course without optimizations g++ -std=c++11 test.cc -o test-gcc the run is slower

2305843005992468481
5208949116

通过使用 g++ -O2 -fverbose-asm -S -std=c++11 test.cc 查看汇编代码,我看到编译器在编译时计算了结果:

By looking at the assembler code using g++ -O2 -fverbose-asm -S -std=c++11 test.cc I see that the compiler computed the result at compile time:

    .globl  main
    .type   main, @function
  main:
  .LFB1530:
    .cfi_startproc
    pushq   %rbx    #
    .cfi_def_cfa_offset 16
    .cfi_offset 3, -16
    call    _ZNSt6chrono3_V212system_clock3nowEv    #
    movabsq $2305843005992468481, %rsi  #,
    movl    $_ZSt4cout, %edi    #,
    movq    %rax, %rbx  #, start
    call    _ZNSo9_M_insertIxEERSoT_    #
    movq    %rax, %rdi  # D.35007,
    call    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_  #
    call    _ZNSt6chrono3_V212system_clock3nowEv    #
    subq    %rbx, %rax  # start, D.35008
    movl    $_ZSt4cout, %edi    #,
    movq    %rax, %rsi  # D.35008, D.35008
    call    _ZNSo9_M_insertIlEERSoT_    #
    movq    %rax, %rdi  # D.35007,
    call    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_  #
    xorl    %eax, %eax  #
    popq    %rbx    #
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
  .LFE1530:
            .size   main, .-main

因此,您只需要在编译器中启用优化(或切换到更好的编译器,例如 海湾合作委员会 4.9)

So you just need to enable optimizations in your compiler (or switch to a better compiler, like GCC 4.9)

顺便说一下,Java 低级优化发生在 JITJITa href="http://en.wikipedia.org/wiki/JVM" rel="nofollow noreferrer">JVM.我不太了解 JAVA,但我认为我不需要打开它们.我知道在 GCC 上你需要启用优化,这当然是提前(例如使用 -O2)

BTW on Java low level optimizations happen in the JIT of the JVM. I don't know JAVA well but I don't think I need to switch them on. I do know that on GCC you need to enable optimizations which of course are ahead of time (e.g. with -O2)

PS:我在 21 世纪从未使用过任何 Microsoft 编译器,因此我无法帮助您在其中启用优化.

最后,我认为这样的微基准测试并不重要.然后进行基准测试来优化您的实际应用.

At last, I dont believe that such microbenchmarks are significant. Benchmark then optimize your real applications.

这篇关于为什么这个简单的 C++ 加法比等效的 Java 慢 6 倍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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