niklas-heer / speed-comparison

A repo which compares the speed of different programming languages.
https://niklas-heer.github.io/speed-comparison
MIT License
475 stars 76 forks source link

Simpler Java more like Python program #106

Open igouy opened 1 year ago

igouy commented 1 year ago

The current Java program seems to have been written with error handling not found in the Python program. Instead this seems sufficient to read a single integer from a known file:

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public final class leibniz {
    public static void main(String[] args) throws FileNotFoundException {        
        var s = new Scanner(new File("rounds.txt")); 
        long rounds = s.nextLong();
        s.close();
        System.out.println( pi(rounds) );
    }

    public static final double pi(long rounds) {
        double sum = 0.0;
        double flip = -1.0;
        for (long i = 1; i <= rounds; i++) {    
            flip *= -1.0;        
            sum += flip / (2*i - 1);               
        }                     
        return sum * 4.0;
    }  
}

rounds = 1,000,000,000

$ hyperfine "/opt/src/jdk-19.0.2/bin/java  -cp .  leibniz"
Benchmark 1: /opt/src/jdk-19.0.2/bin/java  -cp .  leibniz
  Time (mean ± σ):      4.614 s ±  0.023 s    [User: 4.630 s, System: 0.021 s]
  Range (min … max):    4.591 s …  4.645 s    10 runs

Of course, with smaller workloads the constant JVM startup becomes a factor: rounds = 100,000,000

$ hyperfine "/opt/src/jdk-19.0.2/bin/java  -cp .  leibniz"
Benchmark 1: /opt/src/jdk-19.0.2/bin/java  -cp .  leibniz
  Time (mean ± σ):     537.2 ms ±   6.5 ms    [User: 553.2 ms, System: 16.8 ms]
  Range (min … max):   527.5 ms … 551.7 ms    10 runs
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public final class leibniz {
    public static void main(String[] args) throws FileNotFoundException {        
        var s = new Scanner(new File("rounds.txt")); 
        long rounds = s.nextLong();
        s.close();

        double sum = 0.0;
        double flip = -1.0;
        for (long i = 1; i <= rounds; i++) {    
            flip *= -1.0;        
            sum += flip / (2*i - 1);               
        }                     
        System.out.println( sum * 4.0 );
    }
}
$ hyperfine "/opt/src/jdk-19.0.2/bin/java  -cp .  leibniz"
Benchmark 1: /opt/src/jdk-19.0.2/bin/java  -cp .  leibniz
  Time (mean ± σ):      4.631 s ±  0.032 s    [User: 4.647 s, System: 0.020 s]
  Range (min … max):    4.597 s …  4.705 s    10 runs
acrastt commented 1 year ago

Using Scanner isn't efficient though, maybe RandomAccessFile could be more efficient?

igouy commented 1 year ago

isn't efficient

One integer will be read, once. How "efficient" does that need to be?