ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

为什么这个简单的C加法比同等的Java慢6倍?

2019-08-25 03:09:32  阅读:252  来源: 互联网

标签:addition java c performance nanotime


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

我在Java和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)

结果:

Java的:
2305843005992468481
1096361110

C :
2305843005992468481
6544374300

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

我已经做了很长一段时间的Java,但我是C的新手,我的代码有什么问题吗?或者通过简单的计算,C比Java慢?

另外,我在我的C代码中使用了“register”关键字,希望它能带来性能提升,但执行时间完全没有差异,有人可以解释一下吗?

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

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

注意:在适当的条件下,C程序在这个简单的测试中将比Java执行得更好,但是我注意到跳过了很多运行时安全检查,违反了它作为“安全语言”的调试意图,我相信C在性能上会优于Java一个大型数组测试,因为它没有绑定检查

解决方法:

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

// 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

   // 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;
}    

然后编译并运行test.java

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运行速度较慢

2305843005992468481
5208949116

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

    .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

所以你只需要在编译器中启用优化(或切换到更好的编译器,如GCC 4.9)

关于Java低级优化的BTW发生在0700的JIT.我不太了解JAVA,但我不认为我需要打开它们.我知道在GCC上你需要启用优化,这当然是提前的(例如使用-O2)

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

最后,我不相信这样的微基准是重要的. Benchmark然后优化您的实际应用程序.

标签:addition,java,c,performance,nanotime
来源: https://codeday.me/bug/20190825/1714494.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有