152 comments

[ 2.9 ms ] story [ 207 ms ] thread
This leads to the question: How soon until I can use Art as my daily driver?
It is perfectly stable now and almost all common apps are compatible.
I've been using ART as my daily driver since it was released.

It took Whatsapp two weeks to issue an update that made it work with ART. Nothing else and nothing since has posed any problem. In fact, I forgot I was using it until I saw your post.

I've been doing the same with spectacular results, although it's possible that some of the camera crashes (and maybe the IMDB crash I get from time-to-time) are ART-related.
They are not. I'm still on dalvik and the camera crashes and frequently uses 100% cpu in the background.
In Android.Next it seems, as Dalvik was already disabled on the visible source code.
i'm amazed and hurt that dalvik doesn't do inlining (but if JIT will need a few runs to get going... not unreasonable on a phone, if the app can stay resident in memory)

for my fellow perplexed: ART is a java runtime (dalvik alt) https://source.android.com/devices/tech/dalvik/art.html

impressive improvement, x2 dalvik (on this one case...)

BUT for similar GHz (2.3 vs 2.6), intel is x2 to x8 times faster than ARM...

yes, but is not the battery performance worse for Intel's mobile cpus compared to arm?

And side note, we have not seen 54 bit arm cpu performances yet as well

oh yeah, for sure. per mWh, ARM wins. i just meant they aren't grabbing raw performance any time soon... of course, to 'disrupt', it doesn't need to be as fast... just fast enough for what people need. so the Q is: what performance do people need? (related: what tasks do they need to get done?)

for me... i've been coding on, and browsing with, a dual core 1.2GHz cortex 9.... it's fast enough for what I've been doing. (you need a bluetooth keyboard though)

It's not "Intel". Maybe Core i7. And even those chips have a wide variety of performance. Saying "Intel" implies any Intel chips is that fast, when that's not the case.
Even "Core i7" doesn't mean much, since that's marketing lingo that means different things for laptop and desktop, and doesn't cover all the architectural changes that have happened from Nehalem to Haswell.
> dalvik doesn't do inlining (but if JIT will need a few runs to get going...)

Is Dalvik actually a JIT these days? I thought it was just a bytecode interpreter with a register based VM.

In any case, ART seems to be heading down the AOT path, which I think still makes sense in a mobile setting.

Dalvik has had a JIT since Android 2.2. It's quite limited relative to HotSpot due to memory constraints.
well also no intel gcc test
When comparing the intel and arm architectures, GHz doesn't mean much. Transistor technology has evolved to a point where most processors are clocked in that area.

The reason that the intel processor is so much faster is that with a higher power envelope, you can have extra transistors. There transistors can be used to have better branch prediction, have better prefetching, have better SIMD instructions and have more cache. This is what really impacts performance.

If you compare the performance per watt of both processors you see that they are somewhat similar. Keep in mind that ARM processors are also made to be much cheaper than their intel counterparts. Both ARM and Intel do a stellar job in their respective markets.

He keeps saying C but the source code he shows at the end is clearly C++, even if the file has a .c extension.
Yeah, I see that confusion quite often.
It is quite annoying, especially since C++ was not a superset of C for a long time.

Those are two different languages that just happen to have same roots.

Technically, you're right, but practically you don't have to give up much to write C99 that is also valid C++11.
From my own experiences writing either language I have to disagree. C++ may be much (much much) more featureful than C, but if you skip constructs and behavior that aren't strictly a subset of the two you are still missing a lot of modern C, and it's exaggerated by C11. That's not just the obvious high level features like compound literals, designated initializers, VLAs, or anonymous structures/unions. There are a lot of creeping nits about what is defined and undefined in either language, a famous(ly misunderstood) example being type-punning via union, which is allowed in C but undefined behavior in C++.

Except for a few things C++ has imported from C like stdint and vararg macros the truth of your statement depends strongly on how far you personally tend to stray beyond C89 in either direction.

Its very common to see people claiming that Java is faster than a native compiled application. But my gut feeling says otherwise.

I don't know the Java internals on Windows. But someone know why applications with graphical interfaces feels so slow ? My rough guess is that even if Java is fast for mathematical operations, it needs to call native libraries for drawing and this is expensive because of the isolation.

It's a problem with Swing.
It a problem with dumb programmers doing everything on the main UI thread.
And the Java core libraries encouraging it. I like a lot of the JVM, but Swing can go to hell; it makes doing the right thing more difficult than necessary in most cases.
This is almost certainly questionable programming rather than an issue with Java performance in general. Java is the language most beginning programmers start with and they'll do things like create wildly inefficient methods that they proceed to call from the UI thread and so on. Additionally the most used Java UI library (Swing) is not exactly known for its snappiness. The JNI interface introduces overhead but certainly not anywhere near the sort of overhead that should result in UI rendering issues. Long story short, sluggish UIs are bad programming and not related to the programming language they were created in.
I'd add that there aren't many good reasons why UI programming should be slow in any language on any desktop machine around today.

You can draw tens of thousands of things on the fly in a web browser and have it appear instantaneous to a human.

While it's possible to write a Swing application that runs fast (starting fast is a different matter), it takes quite a bit of effort to do so, because the basic tools that it provides lead you towards slow applications and a lot of boilerplace.

Any shop that ever did a bunch of Swing and cared about quality ended up writing their own layer on top of Swing that made those features easier to use, but they still require quite a bit of discipline.

UIs is the kind of place where the whole reactive model actually works well. Create events, subscribe to events, and make each event handler run asynchronously. Use the dispatch thread for events that actually modify frontend-facing, elements, and everything else on background pools.

So the broadly available toolset could only be used well by programmers that are better than the typical guy that was asked to write the UI, and we never got better tools.

Proguard does a lot of optimisations ahead of time and is part of the standard workflow for Android development. It would have been a more fair comparison if Proguard optimisations were enabled (or mentioned if already enabled).
When is Google going to support Go in Android?
When they ever bother to implement this 2012 open ticket.

https://code.google.com/p/android/issues/detail?id=39482

Maybe they're doing it behind the scenes for Android 5.0, and aren't telling us about it? Google isn't exactly doing community development of Android. One can hope.
Actually from the tone of last Google IO, I thought they might use Dart, given some hints about "upcoming stuff", which never materialized.

The original Android team had a few ex-Sun employees from the Java team, so it might also play a role there. Just guessing.

If go can compile to ARM, would it not be a case of just compiling it for ARM and creating a bridge with the Android API?
For it to work they have to:

- Make Go code compile as .so, currently Dalvik/ART are always the app entry points.

- As you say provide a wrapper for all existing APIs, with the problem that many rely on implementation inheritance, not supported by Go. So a 1:1 mapping is not possible.

Not for a long time probably - Go compiler can't make .so shared libraries, which are a requirement for Java / native interop.
Take home: Dalvik still sucks and ART isn't good enough to replace C++ for numerical computation on Android yet?
Solution: native numeric computing library in ART?
Solution: write everything in Assembly.
If you're doing this kind of computation, do it either in Renderscript or C and call into it from JNI.
I've been an Android user since my first smartphone. I've heard several times iPhone users complain that Android equivalents of their iOS apps felt sluggish; though they couldn't pinpoint it exactly. If these numbers are true, it might well be true. Objective-C might not suffer from such a significant slowdown.

I think it is one of the things Apple gets right; they know what matters. As an outsider to the iOS/Mac ecosystem I've often felt that Apple makes trade-offs in productivity to achieve a better experience for the end user. While these tests aren't indicative of typical app performance (most apps aren't doing math in a loop), an order of magnitude performance difference is enough to show up on many apps.

I wonder if Google made a mistake by not choosing native code for Android apps. We have heard forever about Java (and other run-times) getting close to C in performance, but outside of specific test cases native code still runs circles around everything else out there.

The perceived sluggishness of Android was down to how the system was architected, especially around the way the UI thread was prioritised. I say was, because Google threw a lot of hardware and money to workarounds for that problem. It is less noticeable these days. They won't be able to fix it completely without a ground up redesign though.
I also read a breakdown of the touch screen scan rate (the refresh rate at which touch gestures are captured), which was significantly faster for ios devices. That also contributed to the difference in feel. Do you know if android devices have "caught up?"
The scan rate isn't typically the worst factor, which is usually between 120-300hz (meaning a max additional latency of 3 - 30ms), but rather deriving meaning from that data is. Filtering in a noise-free environment typically adds a few scan frames of latency, which is what puts devices in the 60-120ms of latency, and a noisy environment (i.e. plugged in to a cheap charger) can easily up that to a few hundred ms of latency.
The UI thread doesn't get any special treatment on iOS, so unless Android is deprioritizing its UI thread, it doesn't seem likely that this would be a problem.
Doesn't get any special treatment by Android either. All other threads get set to background priority (well, most, but all that we care about), which by default can only consume 10% of CPU resources.
> The perceived sluggishness of Android was down to how the system was architected, especially around the way the UI thread was prioritised

UI thread priority has been debunked time and time again: https://plus.google.com/105051985738280261832/posts/XAZ4CeVP...

Even if it hadn't been, what evidence is there that it would require a ground up redesign?

In the long run, having a more modern language should benefit Android because it means the barrier of entry is lower for programmers.

In the meantime it does seem likely that Java has a non-negligible performance cost. My personal worry is that fast Garbage Collectors usually assume that twice the memory is available than is used. That might put the fact that Android phones typically have more memory than Apple devices in an interesting light.

_Is_ Java significantly more 'modern', than Objective C, though? How? It's not like it's much newer; development started in 1991, vs early 80s for ObjC.
- GC

- namespaces

- memory safe

- you don't have to type @ and [] everywhere to switch between dynamic and static worlds

As for the vm thing, there are also commercial native compilers, even though the general HNer tend not to be aware of them.

> GC

Thus giving Android developers all the fun of dealing with GC pauses. There's a lot to be said for ARC, really; I'm quit glad Apple ditched their brief experiment with ObjC GC.

> namespaces

I'll give you that one; lack of namespaces it the worst thing about ObjC.

> ... Dynamic and static worlds...

I'm not sure what you mean here; Java is a statically typed language, and does not have a 'dynamic world'. ObjC has a fo of optional dynamic typing, which is arguably modern, though also only arguably a good thing.

> I'm quit glad Apple ditched their brief experiment with ObjC GC.

Because they failed to implement a GC that didn't crash all the time, as the Apple forums used to testify before ARC was touted as the best thing since sliced bread.

The wonders of mixing Objective-C libraries compiled in mixed mode.

> I'm not sure what you mean here;

The mixed nature of Objective-C.

With @ and [] one is in Smalltalk land. Without them, one is in C world.

> Java is a statically typed language, and does not have a 'dynamic world'.

Yes it has, via reflection, annotations and dynamic bytecode generation.

> With @ and [] one is in Smalltalk land. Without them, one is in C world.

This is an odd and not particularly true way of looking at things. [] (for message sending), is merely some syntactic sugar for the objc_msgsnd function call.

Which could have been implemented in a better way, e.g. Dylan does dynamic dispatch with multi-methods without requiring me to type [] everywhere. A real pain in non US keyboards.
Also Dynamic casts(w/exceptions) and virtual methods/Dynamic dispatch which do provide some dynamicity not easy/natural in c.
Your first three points are good, but are you seriously suggesting that Java is "more modern" because its method call syntax uses a dot instead of brackets?
Yes, because [] was a pre-processor hack back when Objective-C was invented and the compiler was actually a translator to C.

A means of gathering the code, dump it into a series of objc_msgsnd, without doing much of real compiler work.

There are languages with Smalltalk semantics without forcing me to type @ and [] multiple times per line, a pain in non US keyboards.

Seriously? And all of those {} that you type in Java-land, they're magically easy to type? Which is of course a red-herring, because neither is enough of a drama to be taken seriously. You deal with it for a day or two and then forget about it.
What kind of code are you writing where you have to type @ multiple times per line?

    id map = @{ @"my key": @123};
Surely you're not doing that anywhere close to every line.
Of course, in Java, this would look like (at best, using a third party thing):

ImmutableMap.builder().put("my key", 123).build();

Which hardly seems neater (especially in a more realistic case where you have more than one entry).

The point was the pain to type @ in keyboards other than US.
I found two problems with your reasoning:

First, the overhead of GC depends not only on the heap size, but also on the allocation rate and allocation profile. For reasonable allocation rates found in typical GUI apps, most Java GCs do extremely well having very little additional memory, like only 20% more than the live set size. There is no "twice as much" assumption anywhere in their design.

Second, manual memory managers do have their own overhead too, in form of bookkeeping (e.g. free lists) and internal fragmentation. Fragmentation can be sometimes much worse than GC memory overhead for long running applications, because GC memory overhead is typically bounded, while fragmentation is either unbounded or has extremely high upper bounds (like 10x in "fast" allocators).

> There is no "twice as much" assumption anywhere in their design.

There is in that the nursery collector is often a simple Cheney-style copying collector that wants two semispaces. But that's only one of the generations. There's definitely no requirement that total GC memory is double the used space.

The main issue is the quality of Google's implementation, don't generalize the language vs implementation.

Apparently they haven't done any changes since JIT was introduced in 2.3 version. Additionally we have ART without any information whatsoever about future plans.

While I'm sure Dalvik contributes, Android has had many more serious issues in terms of user responsiveness.

* Android devices have very laggy touch responsiveness in general, while this is something Apple has spent considerable effort optimizing [1]

* Only in recent revisions (Project Butter [2]) has Android made significant improvements to its general UI lag/smoothness issues. At various times, Google employees have gone into extensive descriptions of why the UI is so janky [3][4]

* Many of the default Android elements were for quite a long time, very unoptimized - this included calls w/ lots of overdraw, or lack of node recycling for lists. This forced app developers to take on the bulk of performance optimization. You can take a guess how often that is done well. [5]

Over time, Android the OS, SDK/API, tools have all improved but I believe your second paragraph gets it right. At the end of the day, people at Apple cared a lot about getting the first versions of iOS to feel great. No one at Google cared enough about about it. Even today, when you compare the iPhone to the latest Nexus devices, there's lots of hardware integration issues that will probably never get fixed (outside of community patches).

[1] http://venturebeat.com/2013/09/19/apples-iphone-5-touchscree...

[2] http://www.androidpolice.com/2012/07/12/getting-to-know-andr...

[3] https://plus.google.com/105051985738280261832/posts/2FXDCz8x...

[4] http://lazytechguys.com/news/google-dev-explains-why-android...

[5] http://www.curious-creature.org/2012/12/01/android-performan...

From my experience with working on Android internals, I also get the impression there is a ridiculous amount of IPC happening during normal operation, much of which involves Dalvik components (such as the activity manager) as intermediaries. I've sometimes wondered if this could contribute to a noticeable performance degradation.

Quantifying this IPC might make an interesting experiment and blog post...

The IPC implementation is Binder, and I believe the overhead, even in the G1 days was microseconds.
Binder itself is very fast. I'm mostly thinking about the overhead of higher-level constructs build on top of binder (broadcast intents, etc.) that are handled in Dalvik code and that can become numerous as various apps make connections to various other apps.
> [4] http://lazytechguys.com/news/google-dev-explains-why-android...

Man that was a weird read. Guy spends a few months interning and all of a sudden talks about his profound connection to the campus, the fundamental flaws in the product architecture, but watch out! He may be biased since he will be interning on a competing product the next summer!

Regardless of the facts of the matter this seems like a very non-authoritative source.

It's like no one actually reads Dianne Hackborn's post (#3 above), which was in direct response to that guy's musings going viral when he had no idea what he was talking about.

edit: oops, that was the post that sparked the original specious musings. I meant this followup one: https://plus.google.com/105051985738280261832/posts/XAZ4CeVP...

What drew me to #4 was the baiting headline (Google dev explains...)
[1] The Android code for that test is messed up, and suffers from a race condition and isn't tied to vsync like a normal Android app is. There's a pull request on their github page to fix it, but they haven't accepted it. Regardless, this is a hardware thing not a software one. Apple uses very, very good touch screens. The Nexus 5 also has a really good touch screen, with total touch-to-display latency in the 60ms range.

[4] is total horseshit. He doesn't know squat about any of the platforms. iOS devs also called him out for getting just about everything wrong about how iOS works.

[5] is something iOS devs totally also have to do as well. That is so not an Android-specific thing.

[4] was a post written by a QA intern on a different team. His post was thoroughly debunked by Dianne. I know the guy in person and he is a general loud mouth who never hesitates to spew nonsense about topics that he knows nothing about.
(comment deleted)
Interesting post. I would throw in a social angle. Android will suffer from UI lag until it's scrapped and rewritten, because its early development was heavily influenced by Romain Guy, a developer who was a huge proponent of Swing and who actually thought that JavaFX was a good idea. This is a person who has basically never seen a responsive UI and cannot understand what makes Android "laggy" at a deep level. Some of your other links show that Android is pretty long on people who will write long defensive blog posts, short on people who can make efficient, responsive graphics stacks.

Social problem, basically.

This benchmark is a bit artificial (though still interesting and illuminating), given that much of what we do on our smartphone is not so computationally intensive in our own code, but instead most apps are a relatively thin layer of glue and duct tape that coordinates and orchestrates the underlying native platform code.

The choice of Java/Dalvik does seem like a mistake, and was a carry-over of Android coming from classic J2ME roots, which worked well with Google's love of all things Java.

>The choice of Java/Dalvik does seem like a mistake, and was a carry-over of Android coming from classic J2ME roots, which worked well with Google's love of all things Java.

Where did you get the idea that Android had J2ME roots? It definitely did not.

Rubin came from Danger, which was a J2ME company. They started Android (pre-Google) as yet another J2ME company. When they were eventually acquired by Google, Google didn't want to play ball with Sun, so they went with a clean-room simile, but, to consult actual Google documentation (three years after Android was started)-

http://www.scribd.com/doc/217988654/13/Boot-Loader

the Platform will be compatible with Java Platform, Micro Edition (Java ME).

But they didn't intend to build a J2ME platform, but rather a shim for J2ME apps via some compatibility mode. From some of the original Google documentation:

> "Leverage Java for its existing base of developers. Build a useful app framework (not J2ME). Support J2ME apps in compatibility mode. Provide an opTMobileized JVM (Dalvik)," one slide reads.

I think there's a pretty big difference between building a platform on top of something, and planning to support it via a shim layer. At that point Android was already planning on breaking from J2ME by supporting things like JNI (which is listed on that doc but is explicitly not included in a conforming CLDC implementation for security reasons).

Besides, the only microedition APIs that are in the platform are a few khronos libs, so I really don't think any of that thought really affected Android as we know it today (which was the parents original argument). I will give you that there's more JavaME heritage than I thought, but it was thrown out pretty quickly as far as I can tell.

> I wonder if Google made a mistake by not choosing native code for Android apps.

I would say yes.

> We have heard forever about Java (and other run-times) getting close to C in performance, but outside of specific test cases native code still runs circles around everything else out there.

Please don't mix language vs implementation.

First, the word iphone isn't even mentioned in the article, but its funny how quickly HN drops into an iphone vs. android

Second, the author points out NDK over Java as a solution which is already leveraged by some popular apis transparently from java, such as libgdx.

Finally, the ui is responsive enough. My biggest annoyance whenever I have to help my in laws or my parents with their iphones and there is no back button - I don't notice any significant difference between their iphones and my Galaxy S3, and I'm sure Samsungs phones have only gotten better.

(Equally, my biggest annoyance on Android is often the lack of an on-screen back button, and the small but annoying proportion of times when the hardware back button takes me somewhere other than I expected.)
You can get around the back button part by rooting and allowing double tap of back arrow to jump between last open application. This solved that pain point for me
People don't want to have to root a device to work around usability issues. That's why iOS devices are so popular, out of the box they just work (for the most part).
On the other hand, when you do bump into a problem, you generally can root Android devices, while iOS is getting to be pretty rough there.
I've used both extensively. When iOS screws up, which at least it does in my house regularly[1], you're SOL. We're moving to Android devices slowly (up two Moto Gs at the moment).

[1] we have three iOS devices and I'm the loveless tech support for them.

I was just suggesting this workaround personally after having been frustrated by the back button myself
Which app does that?
after you root, install Xposed framework and you can get the GravityBox module which will enable a ton of customization. Read the tutorials on XDA forums if you need help, enjoy!
>>Finally, the ui is responsive enough.

I have to strongly disagree here. I'm a mobile dev, I work on Android and iOS. My main phone is an iPhone 5s, recently I tried switching OS just so that I would be more comfortable with the different OS's day to day idioms. I couldn't stand Android, it was sooo laggy feeling compared to a iPhone or even a windows 8 phone. Both Apple and Microsoft have large leads in user experience and speed. Don't get me wrong Android is certainly better than either in it's own way but performance and responsiveness are not it's strong suite. 3 apps that the difference was obvious to me are: Google Maps (the ios version feels way smoother), Evernote, and the facebook app. Also see the yahoo weather app the difference was incredible. Phones I used in testing: HTC One, Samsung S4, Nokia Lumia 1520, and iPhone 5S

Granted all of this was based upon personal experience and isn't a scientific study but to me the difference was absolutely clear. Perhaps if I had only used an Android device I wouldn't have noticed the difference as much but having been a long term iOS user I could not stand it.

> Granted all of this was based upon personal experience and isn't a scientific study but to me the difference was absolutely clear.

Thanks for including that line, because my personal experience is the exact opposite. I have a four year old android phone and I dread any time I need to use my wife's one year old ipod. I find the lag on the ipod slow to the point of almost being unusable. Every time I use it, there's at least one point where I'll put down the iPod to go do something else while I wait for it to catch up with me.

It's amazing how much personal experiences can differ.

Edit: updated possibly relevant details

Worth pointing out that there is a pretty big drop in spec from an iPhone 5 to an iPod 5, the SoC is two full generations behind.
This. Also, a year ago Apple was still selling some models of the 4th gen iPod Touches, which are the equivalent of a three year old iPhone 4 but with half the ram.
I have found Android nice to use only on Nexus devices. For whatever reason the other devices always feel slow and have random issues.
I don't know what other devices you've used but Samsung uses its own keyboard on some (maybe all? I've only used a few) of their phones. Its not the fastest thing out there. Switching that out with the Google one can make a huge difference in perception of the phone's performance.
I've used HTC, Samsung, and currently use a Nexus5 full time. Whenever I have to use friends iPhones now they feel really dated compared to the Nexus 5. Android really turned a corner not long ago with 4.x and devices like the Nexus 5.
> Phones I used in testing: HTC One, Samsung S4, Nokia Lumia 1520, and iPhone 5S

Honestly, try a Nexus 5 if you get the chance. The hardware in the phone makes a huge difference (and it's often in places that aren't benchmarked, like the touch controller).

Both iOS and Windows 8 have native compilation only as delivery model and most likely the reason driving ART's design as Dalvik replacement.
The NDK is a total 'bolt-on' solution to the problem, and support within the Android dev tools is basically non-existent.

The biggest tragedy is that Google had a chance to make a better NDK experience with Android Studio, but instead they chose to ignore it completely. With Eclipse you at least had an official add-on for NDK support, but now you're expected to manage it with your Gradle files by hand. Now, even more than before, you're at the whim of solutions on Stack Overflow.

I think having a few ex-Sun Java guys might have influenced that decision. Since all other mobile platforms offer better native support.

This is just my personal opinion.

> If these numbers are true, it might well be true. Objective-C might not suffer from such a significant slowdown.

Kinda. I imagine that if these benchmarks were run on idiomatic Objective-C, they'd be an order of magnitude slower than Java. All method calls are un-inlineable and often require a hash table lookup to resolve.

However, the nice thing about Objective-C is that it's ridiculously easy to write performance-critical stuff in C or C++, then expose it with a nice OO interface. Which means that you (or, more likely, the people who wrote the library you're using) are more likely to bother. That and the lack of GC making latency easier to reason about.

So while it is probably easier to write performant UIs in Objective-C than Java, it isn't because of the reasons mentioned here.

Yes — in fact, it's arguably more natural in most cases to write your performance-critical stuff (e.g. math in loops) in plain C. There's rarely any reason to start boxing values up in NSNumbers and then unboxing them again.

In addition, Apple's Accelerate framework makes it easy and natural to take advantage of SIMD for further speedups — you can get powerful vector operations with single function calls. This seems to have no Android equivalent.

> This seems to have no Android equivalent.

Renderscript?

Thanks — previous Googling hadn't turned this up for some reason.
"If these benchmarks were run on idiomatic Objective-C"

    s/idiomatic/pure/
I haven't programmed it much, but to me, idiomatic objective-C is when you use it as a sort-of scripting layer on top of your C code. No sane programmer would write ten layers of Objective-C message passing code; two or three is fine, on the bottom of your call stack (and hence, rarely executed)
Objective-C message sends always require a hash table lookup to resolve. That is the fast path. (Edit: almost always. I forgot about the vtable path for a few selectors. It doesn't affect most code and I don't think it's even used outside of x86-64, but it is a non-hash-table path.)

However, implying that "require a hash table lookup" is slow isn't really right. The message send implementation is extremely optimized and takes about a dozen CPU cycles to execute last I measured. To put that in perspective, that means that an Objective-C message send on the fast path (which happens 99.99% of the time, the slow path basically just happens once per message/class combo) costs about as much as two C function calls, or one and a half C++ virtual function calls.

Message send overhead in a typical Objective-C app is small. 10% would be high, for really message-heavy code, and 5% is more typical. Most Objective-C code is not messaging so it's still fast.

Take these benchmarks as an example. To write them in "idiomatic Objective-C" you'd change almost nothing. You'd either get rid of the few C++-isms (templates for min/max functions, parameters passed by reference, no big deal) or compile the file as Objective-C++. You'd never write code like this using Objective-C objects. In addition to be slower, it would be harder to write, harder to read, and much larger.

You're right... I sort of contradicted myself there by calling an implementation using Objective-C objects 'idiomatic', since nobody in their right mind would implement that example using NSArrays and boxed values.

My point was really that Objective-C isn't always faster than the equivalent Java (a function call, hash lookup and jump is fast in most contexts, but it's still infinitely slower than nothing, which is the overhead of a JIT-inlined method call), but that being a superset of either C or C++ means that it can be faster when it needs to be. Which is ultimately what matters.

Yep, you can definitely construct Objective-C code that would be way, way, way slower than equivalent Java code. A trivial example would be something like for(int i = 0; i < 1000000000; i++) [obj self];. I imagine any decent Java JIT will be able to detect that this loop does nothing and eliminate it entirely.

However, my point is that not only can you write faster Objective-C code, but that most normal Objective-C code will be faster, because most normal Objective-C code isn't that message heavy. So it's not just that it can be faster, but that it usually will be. Typically. Depending on what you're doing.

Ive tried pointing this out before on HN and was met with a downvote army...my worst ranked post of all time IIRC. The thing is, I didnt need to see benchmarks to know iOS was significantly better. How is it not obvious to everyone else?
> I wonder if Google made a mistake by not choosing native code for Android apps. We have heard forever about Java (and other run-times) getting close to C in performance, but outside of specific test cases native code still runs circles around everything else out there.

You can use native code for Android apps. I do. In the NDK samples there is an app called NativeActivity which is 100% C/C++. You compile an APK without writing any Java/Dalvik code.

From my anecdotal knowledge, most of the popular Android games are written mostly in C++, using the OpenGL ES library, and have a common code base with their iOS counterparts. Maybe they are all native code, maybe they use some Java and JNI stuff, but they are mostly C++. So Android is native on the game side, where it is needed.

A deep look at how all native code runs will show some non-native system code run when it launches, but that becomes pedantry if performance and not purity is the focus.

Android is cleft in two - applications are mostly Java/Dalvik with maybe some JNI access to C/C++ libraries, games from all my discussions with Android game developers are usually mostly the same C++ code and OpenGL ES they are using on iOS.

One example I know a little about is Jigzo. It is an open source game which is C++ and uses OpenGL and SDL libraries. The original developer ported it to iOS. I ported it to Android. Same basic code base, with a few tweaks for each OS. I changed the name from Jigzo to Jigsaw Puzzles on Play though.

The NDK is great for games, but is really not meant for other types of applications. It lacks a ton of mechanisms to interact with other pieces of the platform.
I also do use NDK for my hobby graphics programming, but outside games it is pretty much handicapped and very few people like to write JNI code everywhere. Not to mention the performance issues due to marshaling.

At least now the NDK has some sample source code for JNI helper classes to ease the pain.

Qt is the only sane approach for doing full Android applications in C++, but then one is writing multiplatform code anyway.

Eh, most apps are not doing computations like this in their main thread. Android does have some touch responsiveness issues, but this article has nothing to do with that.
> I wonder if Google made a mistake by not choosing native code for Android apps.

Seeing as Android runs on a lot more than just ARMv7, no, they didn't appear to make a mistake here at all.

Apple can tell developers to compile their app twice for ARMv7 w/ NEON & ARMv8-A64, but is Google going to go tell everyone to compile for ARMv6 (Android devices running this are still shipping), ARMv7 w/o NEON, ARMv7 w/ NEON, ARMv8 (not here yet on Android, but obviously coming), MIPS, X86, etc...?

> We have heard forever about Java (and other run-times) getting close to C in performance, but outside of specific test cases native code still runs circles around everything else out there.

The vast majority of the Java code in an Android app isn't performance-critical either. The code that actually renders an app is all in native anyway. The code to handle touch events and such isn't, but the difference between .1ms and .2ms isn't going to break the 16ms bank either.

They don't 'tell' you, you press Command-B and it happens.

When there are new architectures, you get a warning in XCode and press "Upgrade Project".

Right now my 'default' build is for armv7, armv7s, armv8, x86, x86_64. This setup required no effort on my part. I just created a new project.

(comment deleted)
> ARMv7 w/o NEON

Several of Google's own google apps depend on native libraries. Try to install google apps for android 4.2+ on a device without neon like tegra2 and see how many of them actually work and how many crash with SIGILL.

Well, yeah, when you start developing for Android you quickly find out that Dalvik JIT is kinda crap and it just doesn't do inlining and hotspot optimizations very well.

Which means that pretty much computationaly intensive tasks (e.g. image processing, crypto, etc.) are several orders of magnitude slower than what you're used from desktop JVM. That's especially noticable in Android's BouncyCastle crypto implementation, where standard algorithms like PBKDF#2 derivation function can take ages (e.g. 3 seconds for 10.000 iterations on Nexus 4). Simply just moving those algorithms to C library without any optimizations quickly gives you orders of 100-500x speedups just from the GCC compiler (the before mentioned OpenSSL implementation of the derivation algorithm runs about 80-150ms for same parameters and result). So now we do pretty much any crypto or bitmap algorithms in C and just call C library via JNI.

Of course... most apps don't really do anything computationally expensive so C doesn't give much benefits.

It's not just the tasks you list which are traditionally considered (relatively) computationally intensive, in my experience. I cringe at every loop wondering what the performance cost will be (it's not always clear or predictable). I'm almost at the point where I'd rather just write everything in C++, except for what absolutely cannot be.
> I cringe at every loop wondering what the performance cost will be (it's not always clear or predictable).

Really? I think it's fairly easy to determine what would be expensive vs. what's going to be relatively cheap. I'd love a counterintuitive example to prove me wrong though.

And this is one of the reasons the iPhone feels more responsive with the same (or worse) hardware

Sure, Dalvik may have a JIT but it's difficult to do miracles with a limited amount of memory (and the JIT needs to be fast as well)

The iPhone doesn't feel more responsive.
Actually, the JIT compiler should be able to nail this test so that it is similar to native performance. I suspect the problem is the test itself - see my other comment here.
> And this is one of the reasons the iPhone feels more responsive with the same (or worse) hardware

This is making the assumption that any latency delta is because the system is CPU bound; I suspect this is one of the least likely cases. In general, I suspect apps are going to be I/O or fillrate bound, with some additional latency because touch controllers aren't benchmarked and are only starting to get more love from device manufacturers.

It's interesting to see the saying "Java: compile once, run (slowly) everywhere", which has been around for about as long as Java has, still applies after all these years despite claims that somehow "better technology" in compilers will make the efficiency gap disappear.

You don't have to be a computer scientist to see that the fastest way of doing anything is not doing it at all --- and with Java's architecture, there will always be instructions executed which are completely unnecessary in native code. They can make huge sacrifices in memory consumption (e.g garbage collection that doesn't collect at all, if you have enough memory) to try to reduce things like allocation/deallocation cost, but in the end they're still wasting more resources.

I wonder if he is using ProGuard. He mentions having to manually inline functions, so I think not. It is built-in to the Android build process, nowadays, though, and can be turned on with just a property setting.
Still, using Proguard optimization with Dalvik is ill advised.
Why do you say that?
"Dalvik performs many of its own optimizations, and some of the optimizations performed by ProGuard are incompatible with Dalvik, so to avoid hard-to-figure-out bugs (and because the net performance gain is usually small), the default configuration turns off optimization."

in http://tools.android.com/recent/proguardimprovements

An important aspect of mobile performance that this article doesn't really go into is memory. Its not just about CPU speed. Java performs quite close to C when excess memory is available, but performs poorly under low memory conditions. This is true of all GCed langs. The fact that iOS apps feel snappier is in no small part due to better memory management (ARC).

Source: Why mobile web apps are slow - http://sealedabstract.com/rants/why-mobile-web-apps-are-slow...

This benchmark had nothing to do with low memory conditions. Also modern GCs do not add really that much memory overhead. Typical manual memory allocators bookkeeping/fragmentation have comparable overheads (~10-30%). Problems of Java being memory intensive lie elsewhere - e.g. lack of object inlining (too many pointers everywhere), wide-strings as default, lack of lightweight structures (two words overhead per object), the VM itself, huge OOP libraries (even if you need a single method you need to load a whole class into memory). 90% of memory taken up by my Java IDE is code.

BTW: Your link is about JS, not Java. Performance problems of JS have little to do with GC, there are much bigger problems first.

Modern GCs do not add much overhead when excess memory is available. When the app itself consumes a lot of memory and there is little room available, the GC gets stressed and eats too much CPU time. The chart in the link (taken from some paper) depicts this. The problem is the GC under low memory conditions, not Java.

Yes, the link is about JS. But there are relevant pieces.

Quote from the article: "If you want to process camera images on Android phones for real-time object recognition or content based Augmented Reality you probably heard about the Camera Preview Callback memory Issue. Each time your Java application gets a preview image from the system a new chunk of memory is allocated. When this memory chunk gets freed again by the Garbage Collector the system freezes for 100ms-200ms. This is especially bad if the system is under heavy load (I do object recognition on a phone – hooray it eats as much CPU power as possible). If you browse through Android’s 1.6 source code you realize that this is only because the wrapper (that protects us from the native stuff) allocates a new byte array each time a new frame is available. Build-in native code can, of course, avoid this issue."

No source code for the test framework; can't see how the code is called. If there are repeated calls through JNI, JNI transit time can often be a significant factor.

How many times through the benchmark? Did the JIT get a chance to warm up? Caliper provides a framework that can be used to properly assess performance.

There's no benchmark here without seeing a more complete picture.

Exactly. I wanted to play with the java code to try some possible optimizations but this is difficult without a test driver.
I thought that C on Android compiles to bytecode just like Java, rather than being a true native binary?
Nope, you use gcc to output ARM or MIPS or x86 machine code just like on any other platform.
Nope, the NDK uses the same GCC and Clang that you are familiar with (plus some patches).
Why do we often use graphs when displaying benchmark results? Because it gives us a way of avoiding sentences like this:

Even the slowest native build using clang is not more than 43% slower than the best native build using gcc.

It's weird that the author chose to use field accesses (in every possible instance) instead of local variables in the manually optimized version.
I'd like to see if there's a difference in the output and/or in the speed of the C results without -ffast-math.

That option results some changes in the floating point math (see http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options...) which Java is unable to set, but which may be okay for limited domain the DSP filter works in.

Actually -ffast-math is ok for vast majority of the applications, not just for minority of limited domain apps.

Java has an absolutely horrible floating point support. See http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf

Java code can thus never (in the current language spec) take advantage of vector instructions etc. While in raw integer performance Java might come near native code whenever you use floats Java is going to always lose.

The sad part here is that the decisions made on Java do not even save the programmer from the evils of floating point math. They just cripple the language.

I've seen that set of slides before. But it's quite dense and seems to require (at least for me) Kahan's speech to get all the nuances.

As for the horrible floating point support, are there other factors than lack of signaling NaNs, being unable to set rounding mode and exception policy, floats using floats for intermediate results?

For many purposes such flaws don't seem that bad.

Why is Java code unable to use vector instructions? I guess there's something in the Java spec that prevent compilers from using them, but what is it? I think that the 80-bit floats the Intel FPU offers are used in Java by default unless a method is defined as strictfp, but this a different issue.

I must say pointing to slides that comment on flaws mostly corrected in Java 1.2 with the strictfp keyword. And comments on concerns otherwise only applicable to people who actually do numerical analysis on their code. i.e. all those for who -ffast-math is most likely not acceptable. For those people who actually care about numerical analysis and stability java 8 (finally) gives them a way to do overflow safe code.

The second is that the a decent JVM i.e. not Dalvik do generate vector instruction streams.

I actually think that java code in the next 4 years will start to be much faster than equivalent C code, due to HSAIL and Graals potential to involve GPUs and specialized floating point hardware in an otherwise normal program.

As a developer, Andorid is like EJB, very badly designed for threads android.widget.BaseAdapter with panes and . Even Swing is better.

IOS has these nice loops, more like HMTL.

I hope Google copies Firefox mobile via Gentoo based ChromeOS. Their copying of Java took the worst parts.

'Andorid is the new IE'

This test would only be valid if it ran for at least a few seconds. If the test just takes a fraction of a second then it doesn't give the dalvik JIT compiler a chance to optimize the code. The author doesn't give the running time, or show what value was used for the length parameter.

I'm pretty sure dalvik is NOT generally 17 times slower than native, and this test may just be showing the start-up overhead.