What if there is a bug (or even a misconfiguration in your project)? Or typescript changes over time (and now there are different versions all needed to be supported)? Or what if the types from typescript (designed for programmers) are not always inline with V8 internal representation of objects?) Or what if people push typescript through V8 with compile time errors? (The compiler should have prevented this from happening - but you can pump whatever you want into V8, including things considered broken by typescript).
You only really get any improvement in runtime if your compiler guarantees anything (and bakes it into whatever it is compiling). As of now there are little guarantees with the javascript language (which is what comes out of your typescript compiler). AFAIK typescript is designed to help programmers find common bugs.
Not saying it's not possible, but more work is needed into bridging the two.
Not only that but you can expect to get better performance from the JIT than AOT because the JIT can perform optimisations which are impossible for the compiler.
And you are likely to be disappointed. I think these claims have been made for the last 20 years, and Graal might be the first to deliver something general - all previous successes were very limited to small niches.
I like JITs and what they offer, but very consistently for me and almost everyone I know, in practice AOT works better (faster, consistent, no "heuristic changed in JIT version and now it's slow" surprises).
I can’t help myself, but the JVM performs at par with managed AOT languages (Go, Haskell, OCaml, etc) and strictly slower than the unmanaged AOT languages (C, C++, Rust). The JVM does outperform various AOT Java compilers, but that’s probably an artifact of the decades of optimizations that went into the JVM; the same investment in an AOT compiler would close the gap to within the margin of error. Anyway, sorry for my compulsive nitpicking; hopefully it was interesting.
JVM vs C++ depends very much on the code shapes and what the code is doing. C++ that's very heavy on virtual function calls can be faster written as Java. On the other hand if you use a lot of SIMD intrinsics and things like that, C++ can be a lot faster.
W.R.T. AOT vs JIT, as others are pointing out, Graal is a compiler that can execute in both modes, i.e. it's a comparable compiler. JITC is about a 20% win for relatively static languages like Java and can be massively larger (like 4000%+) for other languages like JavaScript or Ruby. In fact the nature of very dynamic languages like Ruby or Python or JavaScript mean there's little point trying to AOT compile them at all because there'd be almost no optimisations you could safely do ahead of time.
> W.R.T. AOT vs JIT, as others are pointing out, Graal is a compiler that can execute in both modes, i.e. it's a comparable compiler. JITC is about a 20% win for relatively static languages like Java and can be massively larger (like 4000%+) for other languages like JavaScript or Ruby. In fact the nature of very dynamic languages like Ruby or Python or JavaScript mean there's little point trying to AOT compile them at all because there'd be almost no optimisations you could safely do ahead of time.
It seems like you mistook my point for "AOT makes things fast and should be used everywhere" or "JIT is fundamentally slower than AOT"; my only point was that the JVM specifically isn't faster than AOT languages nor is it faster than AOT Java because of JIT specifically (which was how I interpreted jahewson's comment above). It sounds like I agree with you--Graal seems really promising and JIT is pretty great, especially for dynamic languages. :)
my only point was that the JVM specifically isn't faster than AOT languages nor is it faster than AOT Java because of JIT specifically
Hmm, but is there such a thing as an AOT language? You can interpret or JIT compile C and you can interpret, JIT or AOT compile Java too.
I think it's clearly the case that JITC Java is faster than AOT Java. It was maybe unclear for a long time but Graal and SubstrateVM let us compare now. You pay a big performance hit to use a VM-less AOT Java compile. Java is sort of a half-way house between a really dynamic language and a really static language.... it's got dynamic aspects and also static aspects.
You're right that my language was imprecise, but my point stands. JVM does't make Java faster than popular AOT implementations of (for example) Rust or C++ or C, and JVM is almost certainly faster than AOT Java implementations because of decades of optimizations, not because JIT is inherently better than AOT.
> I think it's clearly the case that JITC Java is faster than AOT Java. It was maybe unclear for a long time but Graal and SubstrateVM let us compare now.
Graal is shaping up to be a real game changer, but it's unproven and it's exceptional among JIT implementations. If Graal is all that it's cracked up to be, I wouldn't be surprised if there is a time when all popular JIT implementations perform like Graal, but until such a time, JIT alone doesn't have any clear performance advantages over AOT in general.
Is there an example of at least one such optimization? As JIT is not magic, it also compiles things ahead of time, but a little bit ahead of time and it is very constrained on how much time and resources it can waste. It also can't afford to slow down interpreter too much, can't do excessive profiling, can't do big changes to the code that touch half of all the functions and data structures for example, etc. While AOT can do that and I can't think of anything JIT does that AOT can't do.
Artificial example:
while (true) {
if (timeOfDay < NOON) {
computePi(); //should be inlined before noon, function call after noon
} else {
computeE(); //inline after noon, function call before
}
}And yet, regardless of how much typing info you give it, it loses out to good AOT compilers, for a similarly implemented algorithm.
GraalVM is unique in that it seems to do better than AOT in some cases. I'd wait a couple more years before declaring JIT victory, though.
The belief is that JITs have information, such as variable values and memory access patterns, that an AOT does not. Well, so far hardly any JIT uses that info, and AOTs do have them from through profile feedback; And also, JITs have to amortize compilation effort and runtime saving, whereas AOT doesn't. So the "JIT is obviously >= AOT" is not foregone conclusion.
> You only really get any improvement in runtime if your compiler guarantees anything (and bakes it into whatever it is compiling).
I meant this in reference to runtime speed optimisations coming from types. V8 is improving every day!
I'd say it would be a lot easier to simply focus on the WebAssembly format, you can write your code in a number of (typed) languages and compile into wasm which is designed to be fast.
Javascript already comes with a few decades of bagage, and things are already changing really fast (ES6 and newer versions). Not everyone likes types and the people who do can use typescript (or flow). And the people who need insane performance (games, etc) can use WebAssembly.
It would definitely help moving sections of the code up the tier ladder, not unlike Web Assembly.
I even predict that future typescript versions would include stricter typings optimized for an browser to solve problems like others have mentioned in the thread.
Or just a TypeScript engine in the browser, like ehm Dartium. I guess someone at Microsoft already did this on IE in a hackathon or something.
Even if we consider that good enough or somehow solved, understanding type annotations only helps you reaching peak performance faster. It doesn't really make peak performance faster.
Also there are the PyPy and Dart devs that in theory could use type annotations, but both don't. For PyPy they even have an entry in the FAQ: http://doc.pypy.org/en/latest/faq.html#would-type-annotation...
I don't really know about the details fo Pypy, but from what I gathered from performance talks about V8 between the hidden classes and inline caching it would strongly benefit from these behavioural changes.
Basically, it doesn't preclude the runtime from having to do its analysis, but it makes the analysis & optimisations "hit" at higher rates than they would otherwise do.
Do you? I remember reading that LJ is able to infer ints for e.g. loops with no specific effort (neither performance hit).
Of course it will take a while to be supported everywhere, but they are taking steps in that direction at least.