【问题标题】:Why is C is much slower as compared to Java?为什么 C 比 Java 慢得多?
【发布时间】:2021-01-07 20:06:29
【问题描述】:

所以,我对 C 完全陌生。我正在测试语言的性能。

我做了什么?

我写了 2 个程序,一个用 C 写,一个用 java 做同样的事情,但是 C 比 Java 慢?

这里是程序:

ma​​in.c

#include <stdio.h>
#include <time.h> 
#include <conio.h>

void work();

int main() {
    time_t seconds;     
    seconds = time(NULL); 
    printf("time1 : %ld\n", seconds);
    work();
    seconds = time(NULL); 
    printf("time2 : %ld\n", seconds);
    return 0;
}

void work() {
    int a[1000][500];
    for (int k = 0; k < 10000; ++k) {
        for (int i = 0; i < 1000; ++i) {
            for (int j = 0; j < 500; ++j) { 
                a[i][j] = (i + j) * 5416585;
            }
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        System.out.println("time1 : " + (System.currentTimeMillis() / 1000));
        work();
        System.out.println("time2 : " + (System.currentTimeMillis() / 1000));
    }

    public static void work() {
        int a[][] = new int[1000][500];
        for (int k = 0; k < 10000; ++k) {
            for (int i = 0; i < 1000; ++i) {
                for (int j = 0; j < 500; ++j) { 
                    a[i][j] = (i + j) * 5416585;
                }
            }
        }
    }
}

我的问题:-

所以,我的问题是我读过的所有内容 C 应该快得多,因为它是低级别的,而 Java 本身在虚拟机上运行,​​因此应该相对较慢!但就我而言,输出是:-

C:\>gcc main.c

C:\>javac Main.java

C:\>a
time1 : 1610049457
time2 : 1610049468

C:\>java Main
time1 : 1610049474
time2 : 1610049478

C:\>a
time1 : 1610049487
time2 : 1610049498

C:\>java Main
time1 : 1610049501
time2 : 1610049505

在这里,Java 显然比 C 快得多!

为什么会这样?

【问题讨论】:

  • 为什么你认为虚拟机应该更慢? (更不用说这是一种有问题的衡量 Java 代码性能的方法。)
  • 你的 C 程序很可能有整数溢出,并调用未定义的行为
  • 当使用 -O3 编译时,work 变得一无所有:godbolt.org/z/f5j711 其他基准测试毫无意义
  • 哪些完全优化,C 编译器的优化器比你的测试更聪明。它能够在编译时确定结果,因此它只是在运行时打印预先计算的结果,而不是在运行时计算它。
  • 将预定义的数组改为动态数组;将 5416585 更改为随机数;优化C的编译;再做一次测试。

标签: java c performance gcc


【解决方案1】:

默认情况下,GCC 不应用任何优化,因此生成的代码很慢。相比之下,Java VM 默认启用大多数优化。

$ gcc main.c
$ time ./a.out 
time1 : 1610050160
time2 : 1610050167

real    0m7.113s
user    0m7.112s
sys 0m0.000s
$ gcc -O2 main.c
$ time ./a.out 
time1 : 1610050172
time2 : 1610050172

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

如果查看生成的汇编代码,work 函数的主体在优化版本中被优化掉了:

work:
.LFB12:
    .cfi_startproc
    ret
    .cfi_endproc

【讨论】:

  • 作为比较,没有优化的 Java (java -Xint Main) 在我的机器上运行了 56 秒
猜你喜欢
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2011-01-25
  • 2012-12-20
  • 2017-05-10
  • 1970-01-01
相关资源
最近更新 更多