Search code examples
javajavac

Fastest way to compile small Java files


I'm looking to programmatically compile (not through IDE) a few small classes such as:

public class Sum {
  public int sum(int[] nums) {
    int total = 0;
    for (int i = 0; i < nums.length; i++) {
      total += nums[i];
    }
    return total;
  }
}

Running javac Sum.java takes 429ms on macOS (2.3 GHz Intel Core i5) but in a Kubernetes container (t3.xlarge) with 3VCPU, and 6G of RAM, it takes 640ms. What causes this difference?

I tried different java versions and tried using javax.tools.JavaCompiler but with few files, it takes up to 2 seconds to compile 3 small files like these.

What's the best configuration of hardware/software to make a compilation of these small files fastest?


Solution

  • The number I just got empirically is 5ms/file...

    If you have a lot of Java files to compile, then maybe you care about this. But if that's the case, then the timing numbers you're talking about are not realistic. I wrote this program to compile your test program 1000 times (I created 1000 java files defining classes Sum0 through Sum999.

    import javax.tools.JavaCompiler;
    import javax.tools.ToolProvider;
    
    public class T {
        public static void main(String[] args) {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int N = 1000;
            String[] files = new String[N];
            for (int i = 0 ; i < N ; i++) {
                files[i] = String.format("stage/Sum%d.java", i);
            }
            int result = compiler.run(null, null, null, files);
            System.out.println("Compile result code = " + result);
        }
    }
    

    I ran it, and here are the timing figures for that run:

    > ls stage/*.class | wc -l
    ls: stage/*.class: No such file or directory
           0
    
    > time java T
    Compile result code = 0
    
    real    0m2.511s
    user    0m4.737s
    sys 0m0.549s
    
    > ls stage/*.class | wc -l
        1000
    

    So the total runtime was 4.737 seconds / 1000 = .005 seconds = 5 ms /file. All I can think of is that you're compiling files one at a time, in which case all the time is some kind of startup/teardown cost, and who cares about that.

    The bottom line is that you can probably compile however many Java files you want in just a few seconds, so stop worrying about this.

    This was run on a couple of generations back MacBook Pro.