为什么这个Java程序比同等的Ada快1000倍?

时间:2018-08-01 03:34:45

标签: java ada

我有两个程序,它们简单地循环十亿次并增加一个整数。我正在对两个操作进行计时并比较两个结果。对于Ada程序,我正在使用GNAT FSF编译器。这两个程序都在Windows上运行。我还尝试过运行每个代码的多个代码并平均测得的持续时间,这显示出相同的结果。

我期望发生两件事,要么我的Ada程序编写不正确(我是该语言的新手),要么它编写正确,但是Java编译器正在为我编写的代码做一些事情不知道。

这是Ada程序:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;

procedure Main is
    c : Integer := 1;

    startTime, endTime : Time;
    milliS : Duration;
begin
    startTime := Clock;
    while c <= 1000000000 loop
        c := c + 1;
    end loop;

    endTime := Clock;
    milliS := (endTime - startTime) * 1000;

    put_line("Runtime = " & Duration'Image(milliS) & " milliseconds.");
end Main;

和Java代码:

public class Test {

    public static void main(String[] args) {
        int c = 1;
        long start = System.nanoTime();

        while (c<=1000000000) {
            c = c + 1;
        }

        long stop = System.nanoTime();

        float duration = (float) ((start - stop)/1000000.0);
        System.out.println(duration);
    }
}

Ada可以直接编译为机器代码,因此我希望它比Java程序要快。

2 个答案:

答案 0 :(得分:10)

Java JIT编译器足够聪明,可以意识到可以优化循环。它做到了。

如果您修改Java版本以在最后打印出c的值,您将获得与(未优化的)Ada版本大致相当的执行时间。如果使用c的值,则无法优化循环 1

  

Ada可以直接编译为机器代码,因此我希望它比Java程序要快。

Java JIT编译器也可以将其编译为机器代码。


1-直到我们得到一个 omniscient JIT编译器,该编译器意识到我们对输出没有任何关注:-)

答案 1 :(得分:3)

我无法复制您的问题。

我使用以下代码构建了您的程序

$ gnatmake -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn -O3 main.adb
gcc-6 -c -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn -O3 main.adb

GNAT 6.3.0 20170516
Copyright 1992-2016, Free Software Foundation, Inc.

Compiling: main.adb
Source file time stamp: 2018-08-01 08:20:21
Compiled at: 2018-08-01 10:20:30
 19 lines: No errors
gnatbind-6 -x main.ali
gnatlink-6 main.ali -fstack-check -O3
$

然后我使用time运行程序以检查执行时间:

$ time ./main
Runtime =  0.002000000 milliseconds.
./main  0,00s user 0,00s system 82% cpu 0,005 total
$

如果您不乐观,那么Ada编译器将尝试确保您尽可能在源文本和机器代码之间找到最匹配的内容,以便轻松地验证可执行文件是否正确。 -在这种情况下,您当然应该在循环中获得1_000_000_000次迭代。