Java 17的計算速度比Java 8慢? - marian

banq發表於2022-02-11

儘管最近的一些特性可能會產生 Java 進化的錯覺,但自 Java 8 以來 Java 語言並沒有太大變化

一些內建類有改進,但 Java 效能的整體改進並不容易察覺

如果現代 Java 效能明顯下降怎麼辦?

 

Java中的計算任務

Java 的效能不如 Python,但更方便用於計算。讓我們進行最簡單的實驗,看看現代 Java 的計算能力發生了什麼變化。

任何人都知道的標準計算是斐波那契數的計算。在 Java 中,它可以通過平行計算同步完成,甚至更快。甚至還有一個專門的類RecursiveTask,所以程式碼不像 JavaScript 或 Python 那樣複雜。我嘗試兩種方法來計算斐波那契數。

在我的程式碼中,我重用了來自RecursiveTask. API 建議不要為位置 10 之前的數字啟動新任務。

public class Main {
static long fibonacci(long n) {
    if (n <= 1) {
      return n;
    } else {
      return fibonacci(n - 1) + fibonacci(n - 2);
    }
  }
class Fibonacci extends RecursiveTask<Long> {
final long n;
Fibonacci(long n) {
      this.n = n;
    }
protected Long compute() {
      if (n <= 10) {
        return fibonacci(n);
      }
      Fibonacci f1 = new Fibonacci(n - 1);
      f1.fork();
      Fibonacci f2 = new Fibonacci(n - 2);
      return f2.compute() + f1.join();
    }
  }
Map<String, List<Long>> results = new HashMap<>();
void execute(IntFunction<Long> code, int num, String name) {
    long start = System.currentTimeMillis();
    long r = code.apply(num);
    long time = System.currentTimeMillis() - start;
    results.computeIfAbsent(name, k -> new LinkedList<>()).add(time);
    System.out.println(r + " in " + time + " ms");
  }
void run(int num, int repeats) {
    for (int i = 0; i < repeats; i++) {
      execute(n -> fibonacci(n), num, "one");
      execute(n -> new Fibonacci(n).compute(), num, "multi");
    }
 
    results.forEach((k, v) -> 
   System.out.println(k + " " + v.stream().mapToLong(l -> l).average().getAsDouble()));
  }
public static void main(String... args) {
    new Main().run(Integer.valueOf(args[0]),  Integer.valueOf(args[1]));
  }
}

該程式碼期待兩個數字--斐波那契數列中的數字和重複計算目標數字的次數。最後,程式碼顯示了同步和併發計算目標數的平均時間。

該程式碼沒有vars等現代功能,因為它也將由Java 8執行。

在Java中,編譯器版本很重要。當用 javac 8 編譯的程式碼在 java 17 上執行時,奇怪的事情發生了。為了儘可能準確,我把相同的程式碼用Java 8編譯器編譯成fibonacci8.jar,用Java 17編譯成fibonacci17.jar。

使用以下命令啟動的 jar 的輸出結束:"C:\Program Files\Java\jdk1.8.0_121\bin\java" -jar fibonacci8.jar 40 100

Java 17的計算速度比Java 8慢? - marianJava 17的計算速度比Java 8慢? - marian

將上述 100 次重複的平均值與使用 啟動的 jar 的輸出中的平均值進行比較:"C:\Program Files\Java\jdk-17.0.1\bin\java -jar fibonacci17.jar 40 100"

Java 17的計算速度比Java 8慢? - marian

Java 17 在計算任務上似乎慢 (487–444)/444=9% 和 (280–241)/241=16%。這難以置信。讓我們嘗試另一個數字,45,但只計算了 20 次,因為如您所見,計算需要時間。

Java 17的計算速度比Java 8慢? - marian

Java 17的計算速度比Java 8慢? - marian

現在差異變小了 (5099–4895)/4895=4% 和 (2963–2783)/2783=6%

讓我們試試另一個數字,45,但只計算了 5 次。

Java 17的計算速度比Java 8慢? - marian

您再次看到 Java 17 輸給了 Java 8:(13981–12854)/12854=8% 和 (7982–6927)/6927=15%

結論

確實需要小心使用最新版本的 Java。在某些用例中,例如計算,現代 Java 可能比幾年前釋出的 Java 更糟糕。

原始碼可以從https://github.com/marianc000/fibonacciJava17vs8下載