3 ms·
>Because even a just-in-time compiler is slower than native performance quite frequently. No that's not how it works. The problem with most JIT'd languages is
by b1340276 11y ago
>Because even a just-in-time compiler is slower than native performance quite frequently.
No that's not how it works. The problem with most JIT'd languages is that every variable or field is a pointer, every function call is a virtual call and there are no type signatures to help a compiler. These are the main reasons. If you added structs, nonvirtual functions and type hints you will quickly enter C performance territory (this is basically what asm.js does).
JIT compilers heavily use profiler guided optimizations to avoid the overheads associated with dynamic languages. They can often inline polymorphic function calls because usually 98% the variable points to an instance of type X and the remaining 2% to type Y. Falling back to a normal polymorphic call if the type is not Y. This is something an AOT compiler cannot do.
- xigency 11y ago> This is something an AOT compiler cannot do. Yes, it can. You know the part where the JIT decides whether to execute X or Y? That can easily be implemented in a conditional in compiled code with the two code paths, X and Y. But I'm more interested in the C performance territory. I'm not even interested in cross-compiling code where globals are used or variables change types. It's possible to strip the functions and properties off of a JavaScript prototype and if it's well behaved, which user code is more likely to be than JavaScript libraries, it can be compiled fairly well.
- PeCaN 11y ago> You know the part where the JIT decides whether to execute X or Y? That can easily be implemented in a conditional in compiled code with the two code paths, X and Y. And that's the difference with a JIT compiler: if the value is almost certainly X, then it just emits the code for X and a stub for Y. The stub just bails back into the interpreter. The check is a couple machine instructions and the fast path can be pipelined (since branch prediction is unlikely to fail). An AOT compiler has to include the full code for both X and Y, no matter how unlikely Y is. AOT compiling dynamically typed languages gets you easily 80%-90% unused code.
- xigency 11y agoThen why isn't your argument against code size rather than performance? Seems like an odd position to take. The fast path would also be branch predicted in an AOT case. The only difference in this hypothetical is that the slower path would run faster.
- PeCaN 11y agoBecause with 80%+ unused code, your instruction cache is gonna choke. Also JITs can remove many more type checks, because it knows when a check would be redundant. See e.g. Lazy Basic Block Versioning[1], but existing tracing JITs do quite well also. 1. http://arxiv.org/abs/1411.0352 http://arxiv.org/abs/1411.0352