A Closer Look at Android RunTime (ART) in Android L
anandtech.com
anandtech.com
(Notwithstanding that, as other comments have pointed out, JIT vs AOT is at best a gross oversimplification of the difference between Dalvik and ART.)
The idea of universal VMs go back to UNCOL project (1958).
A few mainframes made use of VMs with some kind of AOT compilation at installation time. The most notorious of it OS/400, still being used.
The first sucessful JIT compilers were designed as part of Smalltalk systems, namely SELF, which JavaScript is a descent of. So of course you hear a lot about it in the context of JavaScript.
Where JIT compilers bring a major win is when compiling dynamic languages.
With strong typed languages, the type of optimization algorithms you can make use of usually win over the limited options JIT compilers have available due to responsiveness limitations.
In the early 80s there was a fad of VM craziness around P-Code virtual machines, which eventually died out when everyone went back to proper compilers.
So this going back to AOT compilation trend, is just the IT circle going around one more time.
That hasn't been an issue on Android so far because those language runtimes would have had to be retooled to generate Dalvik bytecode, and none of them were. (Ruboto, jruby on Android, runs in pure interpreted mode, with a significant performance hit.) But I believe that with Dalvik, it was technically possible. Does ART just close this possibility off?
But you have other problems to solve: How are you going to generate DEX? Generate java bytecode and bring dx to the runtime? Make jruby emit DEX directly?
EDIT: As per the comment below, that is how it's done. You generate Java bytecode and run dx on it.
To the best of my knowledge, there are too projects for generating Dex bytecode directly:
1. dexmaker https://code.google.com/p/dexmaker/ 2. ASMDEX http://asm.ow2.org/asmdex-index.html
A different approach, which I used for Clojure/Android, is to generate JVM bytecode and then use a bundled dx tool to generate Dalvik bytecode from that.
I imagine outside graphics, audio and hardware integration APIs, there is very little done at C level.
Does anyone actually have any real comparisons between Android and iOS? Was there an acknowledged 2x performance benefit for iOS on the same hardware? For games and Ui, for example, wouldn't the GPU be more important?
It will be interesting to see what sort of extensions Google adds to the dex format in the next few years. Hopefully, there will be some efficient lower level language bindings for the UI calls, perhaps?
Why ship DEX proprietary bytecode to be compiled by the same compiler in the same way on hundreds of millions of devices to produce the same output?
It would seem far more logical to compile all the versions needed, one for each device architecture, just once. As other aspects of the apk need to be customised for each device class already, there is not really new overhead.
Going native is a great idea, doing it this way is plain bonkers.
Plus this system also allows apps to take advantage of updates to the compiler without requiring that developers recompile and resubmit. Imagine in 2 years a new ARM version drastically increases performance by using some clever new instructions. If you have pure native code every developer has to recompile their apps to take advantage of the new architecture--with ART, Google handles the update, and every app on the appstore benefits automatically.
It isn't really "insane". There are benefits and detriments. Not least that the same APK can run on many Android versions, across many architectures (x86, AMD64, ARM, ARMv8, MIPS), with many different bits of system hardware.
Further the whole "ART goes native" thing is largely wrong -- Dalvik already compiled to native, storing the JITted code for subsequent uses. ART is just a better performing, more considered rewrite.
Idiomatic use of the NDK is that you always provide Java surrogates for NDK functionality, but of course we know that isn't often the case. Instead developers can and do cross compile into a single APK. That is exactly what I do -- for my NDK components I build to x86 / ARM / MIPS (the last one I can never really justify) and it all goes into one APK. Alternately, and as a middle-grounds, I can make separate APKs for the platforms.
So you lose the Web's ability to be retargeted to arbitrary architectures. You can only be retargeted to architectures that you compiled for. It's the exact same situation as in native code (because it is native code), and has very little in common with the Web's model (which can be retargeted to any architecture, even ones that Web authors didn't "cross-compile to").
By way of example, Nintendo could ship a Wii Browser (PowerPC), because JavaScript is platform independent. But Nintendo couldn't ship a Wii Android app runner and have it play games, because nobody compiles games for PowerPC.
Just to be clear, Android applications can be, and often are, 100% DEX (the vast majority of productivity, video, etc). Because, you hold, there are exception applications that break this model, the whole model is broken? It's saying that the web is broken because ActiveX is used somewhere.
That is horribly specious. It is a dead-end argument by exception.
But let's look at those uncommon apps that use some native code.
a) The majority of the code in most cases will still be in DEX. It will still benefit from device specific compilation.
b) The majority of the NDK code will or should have Java equivalents. When the native code can't be used, DEX code will be used. Again, this is idiomatic.
c) And when those two aren't true, on x86 for instance if you only include ARM, it simply transcodes the ARM native code to x86 native code. It obviously isn't optimized, but it's a pretty decent exception case.
In every case you benefit from the device specific compilation. So what doesn't hold again?
Games are not exactly uncommon apps: https://play.google.com/store/apps/collection/topgrossing?hl...
> a) The majority of the code in most cases will still be in DEX. It will still benefit from device specific compilation.
Do games really bother to ship Java equivalents? I would be really surprised if they did.
> c) And when those two aren't true, on x86 for instance if you only include ARM, it simply transcodes the ARM native code to x86 native code. It obviously isn't optimized, but it's a pretty decent exception case.
Yes, you can use emulators for native code too, but that's hardly a good user experience unless the games are old.
Today, in the world of centralized app stores, there's an argument to be made for directly distributing compiled binaries as an optimization. It still makes sense to use an intermediate format as it allows the most compatibility (i.e. new hardware), but the app store itself could distribute binaries for known/supported handsets as an optimization (it wouldn't surprise me if it didn't already do this).
Is there some great advantage that Windows Phone gains from this? It certainly doesn't seem so.
It's quite remarkable to read people talking about how insane this is, how it's a solution for a different time, etc, when it is working remarkably well (number of people complaining about on phone AOT/JIT time -- about 0. Number of people sure it must be some great issue -- too many). It seems to be a solution for this time.
When Dalvik would have been designed, there wouldn't have been an App Store. The model for mobile development wasn't clear like it is today.
I agree that it's a great solution: the AOT cost is, in practice, tiny. The flexibility (and, I expect, reliability) provided is with the cost.
It allows new architectures to be introduced without requiring that the developer compile them into the APK - and with all the architectures Android supports, that could become large anyway. Compiling on the device allows the manufacturer of that device to ship a compiler optimized for it.
It is possible though that Google could do some compilation steps on their servers, and deliver those through the play store - but the main advantage would be a decrease in installation time.
On the other hand, "managed" code is truly safe from the whims of untrusted developers--if your bytecode format has no way to express some unsafe/privileged native instruction, then the developer can't do that thing on your device, period.
It'd certainly be better if there was a middle step where, say, the Play Store took your Dex-APK and generated a native APK from it. But if devices can't do that step themselves, then sideloading stops working.
Which then means that if you introduce a new architecture then you're reliant on one of those two people re-compiling for it.
This way they can introduce a new architecture, or indeed an improvement to the compiler, and you don't need to do anything other than ship it out to the phone.
It's not just architecture that determines what kind of code you want your compiler to emit.
It is possible, even likely, that the compiler's strategy for a TV plugged into AC power is going to be very different from the compilation for a mobile device with a small battery. And within the worlds of small battery mobile and AC-power or big-battery (e.g. car) devices there will be parameters like heap size, CPU speed, etc. that will vary how the compiler emits code for that device.
Expecting a bytecode designed to be interpreted to be the ideal intermediate representation is a little "bonkers" but it may be good enough that it's not a serious problem, either.
It might have turned out that way but I see no evidence that DEX was designed that way from the start. The claims about DEX performance when Android first came out were that it was twice as fast as interpreted Java bytecode and half the size.
The Dalvik JIT compiler is a nifty design, but there is no evidence DEX was designed to make it easier or better. The JIT compiler was added years after Android shipped.
One can make the general claim that there is no big impediment to producing optimal compiled code from any reasonable bytecode. But I have yet to see anything indicating DEX was designed for compilation or confers any advantages on any compiler design.
It also allows for devices running different architectures (including those not currently supported) or with workarounds for weird architectural bugs to work without having to coordinate that with a central authority.
DEX remains the canonical intermediate and wire form of "native" (meaning compiled-from-java-source) Android apps.
AOT compilation is done at the store. The OS only does the linking at installation time.
Because it isn't, or maybe it won't be?
Think very hard about this. You use your device in different ways than the next guy. If someone did profile collection on the device, and then fed that back into the compiler, you'd get a different executable than the other guy.
Also, building and shipping N hundred binaries from the play store seems like a recipe for disaster.
In fact, i'd strongly argue doing it any other way is plain bonkers.
About the app you mentioned, L is right now a preview build, there are indeed a lot of bugs everywhere. It is not really surprising since we are months away from the release. It does not have anything to do with perfs though.