Rather than bias the results this way, much more interesting would be to test what the speeds are (1) after the VMs have launched, and also (2) when the VMs are hot, that is, Java has compiled your Lisp classes.
Rather than bias the results this way, much more interesting would be to test what the speeds are (1) after the VMs have launched, and also (2) when the VMs are hot, that is, Java has compiled your Lisp classes.
import java.math.BigInteger;
public class Fact {
public static BigInteger fact(BigInteger n) {
if (n.equals(BigInteger.valueOf(1))) {
return BigInteger.valueOf(1);
} else {
return n.multiply(fact(n.subtract(BigInteger.valueOf(1))));
}
}
public static void main(String args[]) {
System.out.println(fact(BigInteger.valueOf(100)));
}
}
With OpenJDK 11.0.14, `time java Fact.java` gives real/user/sys of 0.267s/0.654s/0.033s. But that's not compiling the file first which some programmers aren't even aware is a thing Java can do now, if I do the usual thing of compiling with javac then on the class file `time java Fact` I instead get 0.050s/0.043s/0.010s. For Clojure, `time java -jar /usr/share/clojure-1.10/lib/clojure.jar fact.clj` gives 0.468s/1.069s/0.056s.Edit: for fun since the author mentioned Common Lisp, `time sbcl --no-sysinit --no-userinit --script fact.lisp` gives 0.005s/0.003s/0.002s. If I make a binary out of this instead, `time ./fact` gives 0.003s/0.002s/0.001s`. Since even a time of an empty C program's a.out can sometimes give numbers like 0.001s/0.000s/0.001s I'm clearly running into precision limits of the time command. (CL itself has a time macro that will helpfully give you a processor cycles count, about 290,000 on my machine for this.) I think the author is overestimating the difficulty of adding features to Common Lisp relative to what they plan to do with this toy; CL for scripting works great too.
For Java 11, the docs are on https://docs.oracle.com/en/java/javase/11/vm/class-data-shar...
Latest versions have other improvements like PGO info as well.
Basically what you're suggesting would be the absolute best-case for JIT.
It's not since startup time matters for CLI applications.
Not if you compare to AOT for languages who lack garbage collectors. C, C++, Fortran would still be quite faster.
Of course, Java also has a lot of overhead from the language and implementation level, because of things like no generic lists of integers, no struct embedding leading to lots of pointer-chasing, a tendency for over-allocation, and direct overhead of the advanced JIT itself - performance counters, dummy instructions to support de/re-optimizations on the fly etc.
More specifically, Clojure —
https://stuartsierra.com/2019/12/21/clojure-start-time-in-20...
Can you link to something or explain how to use JIT caches?
https://docs.oracle.com/en/java/javase/18/vm/class-data-shar...
Or how to use it alongside Spring,
https://medium.com/@toparvion/appcds-for-spring-boot-applica...
For OpenJ9,
https://developer.ibm.com/articles/optimize-jvm-startup-with...
On Android, ART does it automatically since Android 7,