4 ms·
FWIW, my experience with JSLT https://github.com/schibsted/jslt/ https://github.com/schibsted/jslt/ was that I first wrote an AST interpreter. Then I and anothe
by larsga 2y ago
FWIW, my experience with JSLT https://github.com/schibsted/jslt/ https://github.com/schibsted/jslt/ was that I first wrote an AST interpreter. Then I and another person independently wrote bytecode interpreters, but the AST interpreter remains faster than both.
It may be that the JVM is simply better at optimizing one type of code than the other.
- brabel 2y agoIf you're writing the interpreters in Java (or other language compiled to JVM bytecode) your code itself is going to be interpreted and JIT'd on the go by the JVM, so it's really difficult to come up with real optimisations to your interpreter. In my experience, the JVM "likes" dumb code: direct, without abstractions on top. Use static final methods for everything, no inheritance, avoid memory allocation (though the JVM is insanely good at optimising small, short memory usage). In a bytecode interpreter you may be tempted to use "proper" type hierarchies with Ops represented by interfaces and things like that. Instead, using an array of objects of the same type which can hold the "variants" (basically, C-style OOP without vtables) of each Op is what makes things go from slow to fast. The code looks very non-idiomatic for Java, of course, but with care can be made pretty readable.
- robinei 2y agoIdeally arrays of primitive values like `long` to store the bytecode represenation for proper good performance. Then use bitwise manipulation to access "fields"
- bruce343434 2y agoAt this point, why not just use C or C++ since you are already writing it like that? Gets rid of the whole middleman.
- gjadi 2y agoBecause you get all the nice tooling around the JVM + safety of running inside the JVM. See https://medium.com/@jadsarmo/why-we-chose-java-for-our-high-frequency-trading-application-600f7c04da94 https://medium.com/@jadsarmo/why-we-chose-java-for-our-high-... / https://news.ycombinator.com/item?id=24895395 https://news.ycombinator.com/item?id=24895395 > An improvement can be discussed in the morning, and be implemented, tested and released in production in the afternoon.
- larsga 2y agoThat's what we did. Still no luck.
- brabel 2y agoWhat are the bottlenecks according to the profiler?
- aardvark179 2y agoI would say that AST interpreters are surprisingly fast on the JVM, and byte code interpreters are surprisingly slow. Maybe one day explicit tail calls combined with invoke dynamic will offer us a path to byte code interpreters that the JIT can optimise based on the predictable nature of byte code sequences, but we’re not there yet. Edit: I should point out that byte code interpreters still have a place because they tend to represent code in a much smaller form. Again this is something that will change over time as things like project Lilliput shrink object headers, but it’s unlikely to go away entirely.
- larsga 2y agoWhat really gave clear performance improvements was generating Java bytecode. In the first attempt I got a 25% speedup, and I'm sure I could have gotten more out of it if I'd spent more time on it.
- aardvark179 2y agoOh yeah, absolutely. The trade off with byte code is that it can feel like threading your language through the class file format’s very particular needle, and you have to pay a larger initial cost generating and loading that class, and you have ongoing costs in terms of the meta space classes consume.