【问题标题】:Java faster than C [duplicate]Java比C快[重复]
【发布时间】:2013-09-20 23:04:37
【问题描述】:

今天我做了一个简单的测试来比较java和c之间的速度——一个简单的循环,使整数“i”从0增加到20亿。

我真的希望 c 语言比 java 更快。我对结果感到惊讶:

java 所花费的时间(以秒为单位):大约1.8

c 所花费的时间(以秒为单位):大约3.6 秒。

我根本不认为 java 是一种更快的语言,但我也不明白为什么在我的简单程序中循环速度是 c 的两倍?

我是否在计划中犯了重大错误?还是MinGW的编译器配置不好?

public class Jrand {

 public static void main (String[] args) {

    long startTime = System.currentTimeMillis();
    int i; 
    for (i = 0; i < 2000000000; i++) {
        // Do nothing!
    }
    long endTime = System.currentTimeMillis();
    float totalTime = (endTime - startTime);

    System.out.println("time: " + totalTime/1000);
 }

}

C 程序

#include<stdio.h>
#include<stdlib.h>
#include <time.h>
int main () {

    clock_t startTime;
    startTime = clock();

    int i;
    for (i = 0; i <= 2000000000; i++) {
        // Do nothing
    }
    clock_t endTime;
    endTime = clock();

    float totalTime = endTime - startTime;
    printf("%f", totalTime/1000);

    return 0;
}

【问题讨论】:

  • 循环在 Java 中很可能被忽略。尝试在循环中做一些有意义的事情,比如更新一个总和并在循环后打印它。另见this thread
  • 优化器。正如桑杰所说。
  • 您是否为 C 构建开启了优化?我猜你可能没有,否则你的 C 代码应该返回 0 秒。
  • 语言 A 永远不会比语言 B 快。不过,语言 A 中的程序 X 可能比语言 B 中的程序 Y 快。
  • “我根本不认为 java 是一种更快的语言” 坚持教条,不管证据如何。优秀(!)

标签: java c performance


【解决方案1】:

如果您想对此进行基准测试,而不是什么都不做,尝试一些有用的东西,比如在每次迭代中计算一些东西。例如计算其他变量中的循环,并确保在最后使用它(例如打印它),这样它就不会被优化。

替代的简单测试可以是线性访问数组(只读)、将元素从一个数组复制到另一个数组(读+写)或对数据执行一些操作。其中一些案例可能很有趣,因为它们打开了几个非常简单的编译器优化,您稍后可以在结果二进制/字节码中看到这些优化,例如循环展开、寄存器分配,甚至可能更复杂的东西,如矢量化或代码运动。另一方面,Java 可能会使用一些更糟糕的技巧,例如 jitting(动态重新编译)

编译器优化的范围很大,你才遇到最基本的——消除无用代码:)

【讨论】:

    【解决方案2】:

    使用除-O0 以外的任何优化级别(例如-O2)重建您的 C 版本,您会发现它在 0 秒内运行。所以 Java 版本什么都不做需要 1.6 秒,而 C 版本什么都不做需要 0.0 秒(实际上,大约 0.00005 秒)。

    【讨论】:

    • 也许在他的系统上。在我的旧笔记本电脑(Core 2 Duo)的第一次运行中,Java 版本需要 0.059 秒……这只是 JVM 的启动时间,可能是磁盘 IO。以防万一这里有任何 Java bashers。
    • 谢谢!我使用了 -O2 并添加了一个简单的计算。循环内。 c语言:0.0000 ...秒。爪哇:6.7 秒。后者也可以优化吗?
    • @owlstead:0.059 秒的启动开销仍然是抨击 Java 的充分理由。它比典型帧率/刷新率的帧时间长。
    • 这是虚拟机的启动时间,运行 3 次后降至 0.01。它需要在后台启动一些线程进行垃圾回收等。也许这对于需要短运行时间的命令行应用程序来说不太有用,但仅此而已。
    • 对于每个网络连接运行一次的程序(通过 inetd、传统 cgi 等)来说也是相当有问题的。
    【解决方案3】:

    Java 在消除不做任何事情的代码方面更加积极。不太可能假设开发人员知道他们在做什么。您不是在计时循环,而是在 java 检测和消除循环需要多长时间。

    简而言之,Java 在无用处通常更快。

    此外,您可能会发现,如果您优化 C 代码并删除调试信息,它会做同样的事情,很可能会更短。

    【讨论】:

    • 任何像样的 C 编译器肯定不会为无用的循环生成任何代码,除非您有意在禁用优化的情况下进行编译,这是一种单步执行程序并能够理解程序流程的工具抽象机器。
    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2017-01-14
    • 2011-05-05
    相关资源
    最近更新 更多