Hacker News new | past | comments | ask | show | jobs | submit login
Follow up to “Android graphics true facts”, or The Reason Android is Laggy (plus.google.com)
330 points by andrewmunn on Dec 5, 2011 | hide | past | favorite | 115 comments



"""It’s because on iOS all UI rendering occurs in a dedicated UI thread with real-time priority. On the other hand, Android follows the traditional PC model of rendering occurring on the main thread with normal priority.""" <- AFAIK this is simply wrong: the events that are later described as blocking rendering are coming in on the main thread, not some special "dedicated" one. The reason things block is because of the way the event loop on that thread is managed (and in fact is directly caused by all of that activity operating on the main thread, which we even often call the "UI thread"), and has nothing to do with threading, and certainly has nothing to do with "real-time priority".

"""On iOS when an app is installing from the app store and you put your finger on the screen, the installation instantly pauses until all rendering is finished.""" <- This is certainly not true. The update of the display for the installation progress might (...might) stop, as that's happening in the UI (aka, "main") thread of SpringBoard (and the event loop management might ignore incoming events that are not related to the touch event until after the gesture completes), but the installation itself is being managed by a background daemon (installd) and will not stop because someone is touching the screen. The operating system is /not/ doing something hilariously insane here, throwing out all computation on the device because someone is accidentally touching it.


He seems like a smart kid, but he's clearly not developed anything on iOS. One of the key things you learn as you're learning how to build an iOS app is that all UI code must be run on the main thread. It even says so right there in the [UIView class reference](http://developer.apple.com/library/ios/#documentation/uikit/...):

> Threading Considerations Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.


On iOS, updates to the UI happen on the main thread, but all animation, surface compositing, and rendered graphics run on the dedicated Core Animation rendering thread.


The user complaints are with regards to delays in event processing ("sloppy" or "laggy" touch events), not general animation that does not involve user input; the specific examples in this article demonstrating how this "dedicated" UI thread with "real-time priority" exists detail touching the screen and watching the system lock up as it is now busy handling the scroll events.

Also, it is my understanding that surface compositing is done in hardware using surface-backed textures, with any software rendering of those surfaces being done on the main UI thread while responding to messages such as drawRect, using CoreGraphics (not CoreAnimation). The only thing that gets shoved to background threads are, AFAIK, animations that are specified in code but then "set free" into the CoreAnimation backend.

I thereby don't feel like these comments adequately defend the statements made in the article: the things it claims are benefits of iOS's graphics architecture either A) work the same on Android (per the post it is responding to from the Android developer regarding the myths of Android hardware surface compositing) or B) actually happen in software on the main/UI thread on iOS. I think we need to look elsewhere for the real cause of Android's horrible touch response. ;(


"The user complaints are with regards to delays in event processing ("sloppy" or "laggy" touch events), not general animation that does not involve user input;"

Obviously you never went through tunnels. When I am playing a 100% offline game (without internet access) and my bus goes in the tunnel, everything stops. Who cares about this "game" when I have tons of networking to do. Networking takes precedence over animation so what happens is any touch events or animation or anything is heavily delayed.

What about the phone? When the call is ending, it can't render a UI update that the button was touched, thus just a delay. It even delays processing the next input event until after the screen switches states. End result? I make a call when I try to hang up or vice versa. Point being that these problems are not exclusive, but the iOS solution is significantly better for these edge cases which are the ones that cause the biggest headaches, they still happen in iOS but very infrequently vs consistently bad every other time.


I think one subtle difference is that in iOS there is some degree of parallelism even in the UI Updates as they happen in the NSRunLoop of the main thread(main NSRunLoop).

So that an UI Update that is waiting for hardware can be delayed and the next UI update in the loop can be processed.

I dont seem to recall any such pattern for Java main thread UI Updates.


An NSRunLoop is normally a CFRunLoop, and a CFRunLoop is pretty much just "get next task; run that task; loop": if one task blocks, it cannot run the next one; the only way for it to look like it is doing multiple things at once is for code to reenter the runloop using CFRunLoopRun(), which is hardly ever used (it increases the size of the stack pretty quickly and breaks assumptions about single-threaded concurrency). Any concurrency with hardware compositing is going to happen at the kernel or hardware levels, not in the app.


You're right in general but starting in iOS4:

"Drawing to a graphics context in UIKit is now thread-safe." http://developer.apple.com/library/ios/#releasenotes/General...

Some things won't work (notably UIWebView which also gets used in UITextView) but you actually can build a view in a NSOperation.


Here's another problem with HeapWorker.c (The android code that does garbage collection, etc.). This is just poor programming imo. Android's thread management is stuck in the 90s. With this type of thread management they're required to trap into the kernel to acquire a mutex. There are obviously severe performance issues with this which partly explains some of the blocking and performance issues in Androids garbage collector, not to mention the possibility of bugs and deadlocks. (see actual android code below). iOS has been migrating away from threads and using dispatch and operation queues (Grand Central Dispatch) instead, which eliminates most of the blocking and possibilities for deadlocks. sometimes performance issues are just results of poor programming.

dvmLockMutex(&gDvm.heapWorkerLock);

//BUG: If a GC happens in here or in the new thread while we hold the lock,

// the GC will deadlock when trying to acquire heapWorkerLock.

if (!dvmCreateInternalThread(&gDvm.heapWorkerHandle, "HeapWorker", heapWorkerThreadStart, NULL))

{ dvmUnlockMutex(&gDvm.heapWorkerLock);

        return false;
    
}

// Block until all pending heap worker work has finished.

void dvmWaitForHeapWorkerIdle() { int cc;

    assert(gDvm.heapWorkerReady);

    dvmChangeStatus(NULL, THREAD_VMWAIT);

    dvmLockMutex(&gDvm.heapWorkerLock);

    /* Wake up the heap worker and wait for it to finish. */
    //TODO(http://b/issue?id=699704): This will deadlock if
    //     called from finalize(), enqueue(), or clear().  We
    //     need to detect when this is called from the HeapWorker
    //     context and just give up.
    dvmSignalHeapWorker(false);
    cc = pthread_cond_wait(&gDvm.heapWorkerIdleCond, &gDvm.heapWorkerLock);
    assert(cc == 0);

    dvmUnlockMutex(&gDvm.heapWorkerLock);

    dvmChangeStatus(NULL, THREAD_RUNNING);
}


With this type of thread management they're required to trap into the kernel to acquire a mutex. There are obviously severe performance issues with this which partly explains some of the blocking and performance issues in Androids garbage collector

Android runs on Linux. Linux uses Futexes (Fast Userspace Mutexes) for locking abstractions like semaphores and mutexes. From Wikipedia -

"A futex consists of a kernelspace wait queue that is attached to an aligned integer in userspace. Multiple processes or threads operate on the integer entirely in user space (using atomic operations to avoid interfering with one another), and only resort to relatively expensive system calls to request operations on the wait queue (for example to wake up waiting processes, or to put the current process on the wait queue). A properly programmed futex-based lock will not use system calls except when the lock is contended; since most operations do not require arbitration between processes, this will not happen in most cases."


Android's garbage collection is handled by Dalvik.


Huh?

thread management they're required to trap into the kernel to acquire a mutex.

Of course GC is handled by the VM. That's not the point here though - the point I thought you made was that the GC uses mutexes and they're required to trap into the kernel. (At least that's how it reads above) That's not the case on Linux. GC uses mutexes which are implemented as futexes[1] that stay in user space for most of the time.

[1] http://www.mail-archive.com/uclibc@uclibc.org/msg02787.html


HeapWorker.c uses pthreads. doing a quick check on one of the functions dvmLockMutex (in Thread.h) uses pthread_mutex_lock.

// Grab a plain mutex.

INLINE void dvmLockMutex(pthread_mutex_t pMutex) {

    int cc __attribute__ ((__unused__)) = 
pthread_mutex_lock(pMutex);

    assert(cc == 0);
}

and here's pthread_mutex_lock.

int pthread_mutex_lock(pthread_mutex_t mutex) { if (mutex->kind == PTHREAD_MUTEX_NORMAL) { if (atomic_exchange(&mutex->lock, 1) != 0) { while (atomic_exchange(&mutex->lock, -1) != 0) {

        if (wait(mutex->event, INFINITE) != 0) return EINVAL;

      }

    }

  }
  else

  {

    pthread_t self = pthread_self();

    if (atomic_exchange(&mutex->lock, 1) == 0)
    {
      mutex->recursion = 1;

      mutex->owner = self;

    }

    else

    {

      if (pthread_equal(mutex->owner, self))

      {
        if (mutex->kind == PTHREAD_MUTEX_RECURSIVE)
          mutex->recursion++;
        else
          return EDEADLK;
      }
      else
      {
        while (atomic_exchange(&mutex->lock, -1) != 0)
        {
          if (wait(mutex->event, INFINITE) != 0) return EINVAL;
          mutex->recursion = 1;
          mutex->owner = self;
        }
      }
    }
  }

  return 0;
}

and here's an excerpt of dalvik/vm/Thread.c

Notes on Threading

All threads are native pthreads. All threads, except the JDWP debugger thread, are visible to code running in the VM and to the debugger. (We don't want the debugger to try to manipulate the thread that listens for instructions from the debugger.) Internal VM threads are in the "system" ThreadGroup, all others are in the "main" ThreadGroup, per convention.

The GC only runs when all threads have been suspended.

...


Regarding the pthread_mutex_lock code you posted: I'd say this shows that in the non-contention case there is no kernel call involved, assuming the used mutexes are of kind PTHREAD_MUTEX_NORMAL; atomic_exchange is likely entirely in user space[1] and thus only if the mutex is already locked will pthread_mutex_lock reach "wait" (wait_event ?) which is probably the kernel call; i.e. those are futexes.

Although I don't understand how the memory management makes use of mutexes (once a (any?) thread realizes that the GC needs to be run, how does it wait until all threads have reached a safe point?), and I don't have time to check ATM.

[1] http://www.insomniacgames.com/tech/articles/0807/files/multi... mentions the pthread_mutex_lock and unlock code including an implementation of atomic_exchange


It is somewhat difficult to read this code (due to the formatting), but this seems like a futex to me: if the lock is not being contended, the atomic_exchange() will take the lock without entering kernel space. If you want to argue with blinkingled, you should look at whether this specific lock is under contention or not, not paste large blocks of code that just demonstrate and prove his argument. ;P


yeah pthreads is implemented using futex. I don't care about the implementation details. It doesn't matter since it's still lock-based (albeit more efficient due to fewer system calls). My original point is, threading is still lock-based. Replacing your lock-based code with queues eliminates many of the penalties associated with locks and also simplifies your remaining code. Instead of using a lock to protect a shared resource, you can instead create a queue to serialize the tasks that access that resource. Queues do not impose the same penalties as locks. For example, queueing a task does not require trapping into the kernel to acquire a mutex (or however mutex is implemented)


Acquiring a mutex on Linux involves reading an integer from memory.

Also, the way a queue prevents two consumers from popping off the same element is the same way a mutex is implemented.


Agreed. The writer here doesn't seem to know what he's talking about. The reason things like WebKit tiles and images in tables don't populate while you're actively scrolling is because of an intentional choice on the part of the programmer. When you're touching the screen the run loop is put into a different mode than the default, and authors tend to write code such that expensive operations (like populating thumbnails in a table) simply don't occur unless the run loop is in the default mode. In fact, a naïve implementation of a tableview with thumbnails will populate those thumbnails as you scroll, and this has a noticeable effect on frame rates.


Right -- the first thing I did after reading a few paragraphs was load a complex web page and try scrolling it -- it continues to render just fine (on a single core iPhone 4). I've got a very old iPod Touch which does seem to lock up page draw when I scroll.

I think that the simple answer is that there's no simple answer -- which is what the earlier post was pretty much saying.


There is a simple answer, but it's not one that most people who are in a position to fix it will like; "it sucks now and I couldn't care less why. Fix it ASAP because it's killing your UX"

And as far as the author of this article goes…maybe he is off on the technical stuff, but he understands the most important, which is that UX is broken in Android for this, among a few other reasons.

Someone open a big report against AOSP? All versions, high priority; "UI Anmations Broken"


has nothing to do with threading, and certainly has nothing to do with "real-time priority"

Well, it has everything to do with real-time priority, because in the case of Android, there is a clear priority inversion. That is, what should be considered the highest-priority work IMHO (updating the UI) is being delayed for other lower-priority work.

Absent other factors, the technically correct way of dealing with this kind of problem is using multiple threads and assigning the right OS priorities to them.

Maybe there are other constraints in iOS development that are causing the devs to wrestle with the main event loop instead.


Yet on iOS, if you do silly work in the main/UI thread (which is very easy to do, as that really is your main thread on which you handle all events, and is thereby something many/most applications you find actually do quite often), it will block all UI updates for that process; claiming that iOS is solving UI lag by having a dedicated UI thread that is marked "real-time priority" is, AFAIK, wrong.

In fact, it is this very property (that on iOS, all UI work must be done from the main thread) that often /causes/ UI lag, and yet somehow Android (where even this author admits using background threads for non-UI work "is the standard Android design pattern" in one of the comments on his post) is the one with the serious UI lag issues <- this mental contradiction is the key problem, and it would be awesome if someone (from Google or wherever) provides a strong explanation.


iOS has the advantage that all apps go through an approval process. If someone is doing lots of work on the main thread and blocking the UI, the reviewer can catch it and suggest to the developer to make their code suck less.


Do people actually get any feedback like this?


Yes, i had an app that in one place didn't asynch a webrequest and locked up the main thread. They emailed me about this.


If we are going to give an advantage I think it would go to Android if thats the only way you get feedback on iOS. Android pops up an Application Not Responsive message if your main thread violates responsiveness thresholds. This is a meta issue to mechanisms for debugging main thread vs. side thread coding.


It can't have anything to do with real-time priority, as iOS does not have any special priority for the main (UI) thread.


Agreed, sort of. The problem is, the wrong problem is addressed by operating systems.

What you may mean by "the highest-priority work (updating the UI)" is really "the lowest-latency work". What we perceive as UI quality is the latency of sucessive events - is it smooth, and fast.

But OSs only give us a big hammer to manage this - priority of threads. Which is very indirectly related to latency. E.g. priority inversion, blocking i/o, the stupid habit of putting OS threads strictly ahead of user threads, and on and on, all impact latency in a way the programmer cannot constrain.

Experimental OSs have tried to use latency as the fundnamental scheduling metric. But each time a new mainstream OS is released, lo and behold it's based on stupid old priority.

So let's acknowledge the fundamental fact, that we're not being given the tools to achieve what we need, and everything we do is a workaround that's more or less successful. It all glitches under the right (wrong) conditions, all approaches are hacks of one sort or another.


On the second point, you're correct for 5.0 at the very least - I just tried it. Touching and even actively panning back and forth (never releasing) doesn't even pause the loading-bar updating, and I even discovered badges update during this as well.

For 4.x, if I remember correctly, it would pause the rendering. But I experimented a little then too, and it didn't pause the install at all - it'd just jump when you released.


I'm totally confused. When you say "the events that are later described as blocking rendering are coming in on the main thread, not some special "dedicated" one" are you talking about iOS or Android? I can't make sense of your post either way.


saurik is talking about iOS.


+1 I think this Saurik guy knows what he's talking about... Now where have I heard that name before? (hint his software runs on over 2 million devices)


The great part about Android being open source is that you can go look at the source to see that the UI thread is not a "normal priority" thread [0]. There are very few things that run at higher priority (and they're listed right there): the threads related to audio and the hardware interaction (power buttons, etc.).

Last time I tried it, Android did not let you create a thread with higher priority than the UI thread.

[0] http://developer.android.com/reference/android/os/Process.ht...


As I said in the other thread, there are two patterns, one is a Delegate pattern (IOS) where draw method lookup per pixel coordinate is trivial, and the other is a listener pattern, where view layout, composition and superposition is trivial. One is easy 98% of the time and super hard 2% of the time (iOS) and the other is relatively slow all the time but with much more potential for cross-process interactions.

In Android, you can have a translucent popups from App#1 appear on top of any sort of screen of App#2. You can't have this on iOS. At all.

On the other hand, animations and scrolling are blazing fast on iOS without any need for superior hardware.

I honestly believe that this alone explains the "lacking" in performance that Android suffers from: it targets super high-end multi-core devices, with JIT compilers and optimizers that don't exist yet, in order to allow functionalities that are unclear to everyone of us.

Shameless plug: I made an app (1) that illustrates what iOS will never be able to do. The question is, will anyone ever need that sort of app on their phone?

(1) https://market.android.com/details?id=com.fairyteller.linkpr...


What keeps you from having a translucent popup from App #1 appear on top of any sort of screen from App #2 is not iOS's rendering architecture: it is that you are not allowed to, as one application, do any sort of computation while another one is happening.

To be clear, we do this all of the time on jailbroken devices (where we have access to write apps with true multitasking, and can also just add code as required to SpringBoard itself, which is acting as the window manager): you just create a transparent UIView and put it in a new UIWindow; there are seriously no issues doing this.

In the end, every UIView is backed by a CoreSurfaceBuffer (I think "Core" got renamed to "IO" at some point, if you look this stuff up), which are managed by a kernel driver that allows processes to pass these buffers (which may be backed by video, not system, memory) to each other, and in the end they mostly composited (with alpha blending) in hardware.


Pretty close on the iOS stuff:

1. All* rendering takes place on the main thread in iOS.

2. The main thread doesn't always have the highest priority. In fact, its priority level changes throughout an application.

3. There is more than just one reason iOS rendering is so fast. Here are two important ones:

a. Animation is actually the basis of the entire rendering system. On desktop Cocoa, the drawing system was a little dated. The mistakes learned from this system and the desire to have fast animation led to the Core Animation framework and the idea of "layers". The ability to quickly composite layers (without moving any data from between the CPU and GPU) and only redraw when necessary is huge.

b. The batching together of drawing updates at the end of an event instead of on an as needed basis allows for huge performance gains.

* It is possible to draw in a background thread, but is reserved for particular situations (maps, web content, etc.). Table views do not fall into this category.


Do you think games will ever take advantage of this on OSX to start giving Apple an edge? Right now I still have to have a Windows machine if I want to do any gaming.


When it comes to games, OpenGL is still the best option. The animation system works well for moving around interface elements in two dimensions. The animation system does not work well for 3D or when you are modifying the bitmap content of a layer on the screen.

Will OSX ever catch up to Windows for games? Maybe. Some game companies take the approach of writing everything in OpenGL to make it easier to port between systems, writing a layer of native code to support their cross-platform code.

However, some studios use DirectX which is windows-only. The popularity of OSX and iOS will only increase the pressure on game developers (and engine developers) to write code that is easier to port.


I'd be interested to learn what the deal is with sound on Android. I'm a musician and love the software instruments on the iPhone/iPod touch... they're a joy to play. On my relatively modern Android phone (Motorola Droid 2), instruments are so laggy they are absolutely unplayable. A key press results in a sound up to half a second later, sometimes never. The response improved slightly with the upgrade to Gingerbread, but not enough. iOS instruments are responsive enough you could play them in concert if desired... on the other hand, I can't even entertain myself with the Android music apps.

Is this just the difference between Java and Obj. C?


Android is all around inhospitable to music apps. The link in a sibling post here is just part of the problem - as far as I can tell, Android has no libraries that are useful for serious A/V work.

On iOS, in the span of a short morning I can hook up a button or slider to send out MIDI messages over WiFi to my MBP and route it to any device I want; I have no idea how to get the equivalent setup on Android. What if I want to decode an mp3 and process the resulting audio? I can tell you two ways on iOS, I know of a vague direction that might work for Android. You have to dive down into the NDK to do it, too. What about compositing video? Well...

Seriously, here is AVFoundation on iOS. This is a high-ish level Obj-C interface for mucking about with AVAssets, which can be audio or video:

http://developer.apple.com/library/mac/#documentation/AVFoun...

This is just a single library dedicated to a single level of abstraction. Video composition, audio mixing, playback control and monitoring... there's a lot going on just here. You've also got CoreMIDI, AudioQueues, AudioUnits/AUGraphs, MusicPlayer... they're not easy to pick up, but they're there and they can do serious work.

Here is what you can do in Java on Android:

http://developer.android.com/reference/android/media/package...

You can play encoded media, you can capture a raw input stream or direct it to an encoded file, you can play raw PCM... that's it. Really. To my knowledge, I'm not exaggerating when I say that - I'd be in debt to whoever proved me wrong, so please do!

For graphics on Android, there's usually something analogous you can get by with. For audio, though, it's just... not there at all.


IIRC, you can use OpenSL (which is somewhat like OpenAL) on Android, and that "should" provide you with a lower latency audio feed, but you're right that it isn't anywhere as nice as specifying your PCM format of choice and passing in your block reference to the audio component like you get on iOS.


It's a known issue and people have been complaining about it for years now: http://code.google.com/p/android/issues/detail?id=3434


There are hacks around it and there have been improvements since I played with the framework. However the hacks are ugly... I wrote a little tiny procedural 'music' app when I first got my Nexus One (android 2.2 i think). This was a workaround for lack of midi support and the latency issue. Anyway, not a shameless plug, its free and no ads, was just a "learn android" thing and was never polished at all. I'll dig out the code and get it up on GitHub if anyone wants to play with it.

[0] https://market.android.com/details?id=xian.bubbles&hl=en


This was on HN a couple of days ago and it turns out that it's down to the sizes of the sample buffers each OS allocates.

From what I understand, Android will only give an app a large buffer, so when the app starts filling up that buffed, it may take a little while for the 'playhead' (is there a more technical term?) to get around to playing those samples.

On iOS however, an app can request a much smaller sample buffer, so there's less lag time between when an app fills that buffer and when the samples actually get played.


The takeaway for me is this: Android and iOS' creators made different tradeoffs in their UI programming. The iOS creators, overall, correctly predicted that a fast, smooth, responsive UI was something that users would care about enough that it was okay to pay a performance cost in other areas in order to make the UI as responsive as it is on iOS devices. Android's creators made a different tradeoff, and the UI on Android devices showed clearly - and continues to show - the problems with that tradeoff.


I think it the takeaway is slightly different: When many of Android's fundamental design decisions were made, specifically making UI animations take place in a normally-scheduled application thread, the prime competition/inspiration was the keyboard- and trackpad-driven interfaces of competitors such as Blackberry.

Apple, on the other hand, decided that a touch-based interface was the way to go. As such, Apple designed iOS to make rendering in a special, real-time priority thread to ensure responsiveness.


If this is true than it blows a hole in the assumption that Android was designed with a touchscreen in mind.



The interesting thing would be an estimate of the amount of work needed to move the android ui-rendering to its separate real-time thread. Would it even be realistically possible?


I'm not so sure that the iOS creators predicted anything. They started off with OS X, which already had a smooth, responsive, GPU backed UI (Cocoa/Quartz Extreme). I don't think that they had to compromise on performance, but they did have to spend extra money on a GPU.

Likewise, a good low latency sound system with MIDI support was added to iOS not because Apple correctly predicted that smartphones and tablets would be popular for music production, but because those were features already present in OSX.

AFAIK, the Android designers started out making a Blackberry clone, and creating a similar software stack would have been a lot more work at a time when the competitors were all running 2D GUIs with no GPU acceleration or fancy animations.


This is correct. However, the Android team made their decision with the assumption that Android would power keyboard and trackball devices. That was never the case, so they made the wrong decision based on a faulty premise.


Android would power keyboard and trackball devices. That was never the case

Er, there are a lot of Android devices that are keyboard and trackball powered.


I think he meant to say kb devices without touch screens.


I don't know about saying "That was never the case...". At the time the decision was made, a blackberry-style device was indeed the target. The problem was when the target shifted to iPhone instead.


Apple is also willing to put a lot of burden on the developers. Having a separate UI thread is more difficult than doing all rendering in the main application thread. Supporting only native code without garbage collection is also more difficult on developers too.


Except that all UI stuff is done in the applications main thread ...


How was the iOS decision more "correct"? Android is clearly succeeding despite the lack of UI refinement, so it's hard to hold one as victorious.

There is definitely a different philosophy, though. The Android approach was that it was better to be correct -- if you scroll a page or a webpage, that what scrolls into the viewport needs to be correct, while iOS happily scrolled in a checkerboard. I prefer the stock Android approach (some devices, such as the GS II, sub in the "better to be fast" approach, giving smoother superficial interactivity) so long as there is enough hardware that the result isn't too painful.


> The Android approach was that it was better to be correct

How do you define "correct"? The "correct" behavior is dependent on what you're trying to achieve. What you're trying to achieve should be defined with reference to the user: what will make the user happiest?

In a multi-touch interface, where you're trying to maintain the direct manipulation illusion, preserving "feel" at the expense of showing the rendered content a split-second earlier is almost certainly the right trade-off. The user will chalk the checkerboard up to page loading and their internet connection. They'll chalk hiccups in manipulation up to the device itself.


There are big assumptions. Preference for lag or artifacts is subjective (for example, the checkerboard drives me nuts; I prefer occasional shutter). Users will chalk up the checkerboard to device too, as they never seen anything similar on any other device.


The iOS decision was more correct because it has proven itself in the marketplace. Consumers overwhelmingly demand touch interfaces on their smartphones and tablets, as opposed to stylus, trackball, or any other that has come before it.

Android started as a platform trying to out-Blackberry RIM. When the iPhone was released in 2007 they switched to a model of trying to out-do iOS.


"Proven itself" how, exactly? Last I checked Android devices were outselling iOS. Now, there's room for argument here about what the proper design is for a mobile OS. But if you're going to support your platform flamage with statements like "Consumers overwhelmingly demand" you need to synchronize the argument with the facts.


Total devices in the field. At Apple's iPhone 4S launch event on October 4th, CEO Tim Cook said that the company had sold 250 million iOS devices to date--including iPhones, iPod Touches, iPads, and (I assume) current-generation Apple TVs. Shortly thereafter, Google CEO Larry Page said that 190 million Android devices had been "activated." (Google talks about units in terms of activations, not sales.) http://news.cnet.com/8301-33200_3-57323943-290/ios-vs-androi... Dated Nov 14, 2011.


So very near equivalence in sales (which look even closer if you take into account the fact that iOS has been on the market about 30% longer than Android) is an argument for consumers "overwhelmingly demanding" the tighter animation scheduling of iOS?

I'd say if anything this argues for a total absence of correlation with user experience, no?


"Last I checked Android devices were outselling iOS."

Source? There have been many reports of Android phones outselling the iPhone, but I am not familiar with the ones about Android devices outselling iOS devices (iPod touch, iPad, etc.)


Probably because that would be incredibly difficult to calculate. There isn't really an Android equivalent of an iPod, for a start. Do we include Nook and Kindle Fire devices in the figures? Because that would affect things.

At least cellphones is a more like-for-like comparison.


I do not disagree, but the parent referred to data that shows Android vs. all iOS devices, so I am quite interested in reading it.


"Proven itself" can mean that iOS grosses more than Android. Last I checked iOS users spend more on apps/services than their Android counterparts.


If that's because Android's interface is laggy, then why do people keep buying Androids?

IMHO, iOS users spend more on apps because iTunes is better than Android's Marketplace - this may have been a deliberate decision by Google nonetheless. Did you know that I am not allowed to sell Android apps in the Marketplace because my country is still not approved for registering a Google Merchant account? That's right, it's almost 2012 and while I can sell apps on iTunes, I can't on Android's Marketplace. However I have no problem integrating AdMob in those apps. So it's like Google wants ad-supported instead of paid apps, which considering their main business model it isn't that shocking.

However, you can't say that Android and its UI is not a success.


People keep buying Android for lots of reasons, they can be a lot cheaper, they have more options (keyboards, big screens), they are pushed a lot by carriers, lots of carriers don't carry the iPhone.

The interface problem with Android might come in to play when people are considering their second smartphone, and devices are a lot faster these days. Of course, no one should need a dual core or quad core CPU for a smooth experience on their phone.


That doesn't answer the question, which has a context: if people don't buy Android apps because the interface is laggy, then why do they keep buying Androids?

I have an iPhone 3GS and a Galaxy S which recently upgraded to Gingerbread. The iPhone experience is indeed more "smooth", however that doesn't bother me because the advantages that my Galaxy S gives me outweigh the smoothness of the iPhone.

As an example, on my Galaxy S I was free to install a calls / SMS blocker. You can blacklist certain numbers and then it's as if those numbers don't exist - not only it blocks the calls / messages, but it also removes all traces from the logs. Last time I checked these types of apps where banned from iTunes. On Android it isn't so cut and dry either, as these apps are using private APIs that aren't documented, however they are allowed on the Marketplace.

Another example would be the kickass integration my device has with my Google Apps account. For instance all my phone numbers are synchronized with Google Contacts. And don't get me wrong, I'm sure this is only a matter of preferences and I could probably do the same thing on the iPhone, however this works both ways and I'm having an easier time with my Android to do what I want.

The only annoyance I have with my Galaxy S is the slow upgrade cycle. It will probably take forever for Samsung to deliver to me an upgrade to Android 4. Which is why my next phone will be a Google Galaxy Nexus, or whatever blessed phone will come next after it.


> then why do people keep buying Androids?

Do they? The big Android surge only came in the last year, so the vast majority of Android users are on their first.


That wasn't at all the focus of the comment that I replied to. I get that you're on this "keyboard/trackball" thing (sidenote -- did you know that Android devices still come out with keyboards and trackballs?), however the difference between the two platforms is largely simple architectural differences having nothing to do with form factor.


>Android is clearly succeeding despite the lack of UI refinement

I'm not sure Android is clearly succeeding. Samsung, etc. are succeeding. If they switch to a superior OS (Windows?) but keep similar pricing I suspect only a very small core of hardcore Android fans would remain.


“...a lot of the work we have to do today is because of certain choices made years ago... ...having the UI thread handle animations is the biggest problem...An easy solution would of course to create a new UI toolkit but there are many downsides to this also.”

What would such a re-write look like, from a practical coding point-of-view? Couldn't this be done in a way that is transparent to the calling code, or would there have to be a fundamental re-write of the SDK, i.e., the UI thread no longer be the main thread?


That jumped out at me as well. I think there would definitely be a way to have most if not all of the underlying API calls set up to do this, without even needing to recompile the application.


If you move code that used to run (and was tested to) on the main thread to another thread, and run that thread in parallel with the main thread, you are creating a huge opportunity for race conditions.

Some applications may run fine, but I bet you will find a lot that do not, even ignoring timing differences that may cause problems with games.


I guess I don't see how that's any different than performing any other blocking operation off the main/UI thread, either on a hand-rolled secondary thread or using a util class like AsyncTask which handles that for you.

It seems to me race conditions are no more or less of a concern for rendering animations than updating data -- and probably less, actually, since there's probably not much contention for animation resources, and if there is contention, synchronization of access to drawables should be straightforward.


The post I replied to speculated that it would be possible to change the system's behavior without recompiling apps.

That would change the rules from "model updates and screen redraws never run concurrently" to "...will typically run concurrently". I think you agree that is asking for problems.

Of course, it is possible to adjust the system to apply different rules to different apps, but then apps would have to be changed to advertise "I am fine with running updates on a different thread". I think newer versions of Android already have some of that.


This is almost certainly the right answer. Synchronization/priority is the #1 culprit when people complain that a UI is "laggy." It was why BeOS was so renowned for being snappy--all rendering was done in a separate high-priority thread. It's also one of the reasons Linux has always been criticized for a laggy UI: the X server/application/window manager triumvirate isn't so much slow as it is a total mess from a priority point of view. You end up needing priority-shifting schemes UNIX doesn't have (quickly shifting priority from the WM to the app to the X server as an event flows from the X server through the WM to the app).


Good article! But I have to question the default assumption that iOS isn't laggy. I'm using an old iPhone 3G and it has become laggy as hell over the years. Scrolling on a web page is only ever smooth once a page has finished rendering -- and often not even then. The map application has become so laggy as to be completely unusable; every scroll or keypress takes 20-30 seconds to register (not exaggerating). Installing an app more or less bricks the UI throughout. I'm sure that these problems do not exist on modern iOS hardware -- but on that basis, the only fair comparison is with modern top-of-the-line Android hardware.

(In other news, I just ordered my Galaxy Nexus yesterday and am rather looking forward to it. Can you tell?)

The trick is that there is effectively only ever one model iPhone / iPad at a time -- so right now it's the 4S, for example, that captures all the mindshare and forms the basis of comparison. Legacy iOS devices simply cannot keep up, and certainly do not maintain the buttery-smooth experience that people identify with iOS. But nobody appreciates this, because legacy iOS devices aren't an active force on the market. Android devices, meanwhile, come in many hardware configurations, some of which are much more analogous to my old laggy 3G than to the latest iOS hotness.

This isn't an excuse: it just means that Android has set a harder task for itself than iOS has. But that's no reason not to succeed at that task. 15 years ago, my hand-built BeOS box gave me an unbreakably buttery UI -- even during obnoxious geek demos such as simultaneously playing 30 different videos in 30 different windows -- so there's no reason that ANY computing device, even a very cheap one, should not be able to match that performance today. This article gives a good insight into how Android is failing to do so, and what some of the solutions might be.


> Installing an app more or less bricks the UI throughout. I'm sure that these problems do not exist on modern iOS hardware -- but on that basis, the only fair comparison is with modern top-of-the-line Android hardware.

That's not the "only" fair comparison. The 3G is a three and a half year old device. It's also severely memory constrained and probably shouldn't have gotten iOS 4 to begin with. You're certainly running into paging issues: iOS doesn't have a backing store for virtual memory, but it will drop and reload read only pages out of flash storage when it's memory constrained.

The iPhone 4 is almost 18 months old and compares quite favorably with year-newer Android devices on the UI responsiveness front.


Not just the iPhone 4, the 3GS holds up really well with iOS 5 on it as well.

I have a 3G and like you said it should have never gotten iOS 4. But the 3GS is just fine.


Finally an answer and seems like a reasonable one. For a time I had both a Nexus One and iPhone 3GS. The Nexus One was faster in just about about everything, but using it just felt like work. The iPhone comparatively was a pleasure to use.


I don't know if his technical explanation is correct or not, but he is absolutely right about the importance of responsiveness. I was an Android early adopter (G1) and while I could put up with slower HTML rendering (for example), I could not tolerate the poor responsiveness.


Interesting to finally see some informed discussion about this going on. In the meantime I've scripted my Galaxy S to turn off syncing when the screen is turned on. It helps a lot to combat lag, as the phone often had the annoying (but understandable) habit of starting a sync when it was awakened by me: resulting in slowness just when I tried to use the device.


Can someone explain what is "laggy" about android?

I have a Droid bionic (second Android phone) and a Kindle Fire. What lag should I be suffering?


Can't speak for the bionic, but on a Kindle if you scroll in a webpage, you will notice a very low framerate. It is far less smooth than on, say, an iPad.

Other lag is also present in the initial part of scrolling. Android takes a bit longer than iOS to respond to your fingers' movements. Its on the order of milliseconds, but it is noticeable if you compare it to an iOS device.


Hmm ... is this still an issue with dual core Android phones ? I have two Android phones, Galaxy S2 and Galaxy Nexus and both are as smooth as butter. Both feel faster than my first gen Ipad.


Yes.

A lot of Android's rendering takes place on the CPU and a lot of it is small batches of serial work that isn't very well suited for concurrent execution on multiple cores.


Isn't Google's staff working under NDA?

I love the open discussion about Android's weakest point and I appreciate opinions from all side, in particular those from inside Google -- but this uncoordinated communication on G+ addressing problems w/o delivering a solution damages Android's image to some extent.


It would be nice if Google could just say "responsiveness: we fixed it" but meanwhile I think these recent discussions are far better than the uninformed trolling that was going on before.


Did you see the part about "I’m interning with the Windows Phone team starting in January"?

Still, I don't have experience with iOS devices, but my Nexus S tends to be so laggy at times that apps crash frequently. (I had attributed it to GC).


>Still, I don't have experience with iOS devices, but my Nexus S tends to be so laggy at times that apps crash frequently.

This sounds more like poorly written apps than an issue from the article.

For example if you are scrolling a list view and it slows down to the point of crashing, the application probably isn't caching views or has a memory leak (application authors fault).

If your device gets sluggish and you get miscellaneous force closes I would look for applications with background services that are doing more work than they should be.


How's that heavily damaging? Google is known to be open about its workings, and I think most people agree that an engineer explaining underlying concepts is a positive thing. Putting up NDAs on every little thing is just silly and annoying.


It's an open source project. Google doesn't make any money from Android. It's just something they do for fun to advance their other business goals.


This isn't a "follow-up", per se.

Nonetheless, while Android continually works to smooth out the rough edges -- helped along by the march of technology -- this is something that is a bit overblown: Minor jutters of the interface is something that primarily irritates people as a relative thing, not as an absolute thing.

If you are a developer or a reviewer and you regularly use an iOS device and an Android device, the difference is evident and jarring. If you're an end-use it quickly disappears and is a non-issue. It just isn't a real problem for end users.

It's the same as getting an upgrade to your PC, a new video card, etc. You were perfectly happy before, but relative to your new reality the old one seems subpar, and you overestimate how much it interferes with your enjoyment of the device.


That directly contradicts my own experience with Android. I bought a HTC Hero as my first smartphone, so I didn't have any reference points to compare it with. Over 18 painful months of owning that phone I never got used to the lagginess of the UI. Not to the point where it faded into the background, anyway: I learnt to anticipate the lag, but it never stopped being annoying. So much so that when it came time to replace the phone, there was no way I was considering an Android phone again.

Basically, I'm an existence proof against your argument (and now a happy iPhone owner too).


There was a dark period in Android's existence where a very immature OS came together with underpowered hardware (the GPU in an iPhone 3G demolished the GPU in the Hero) and created a pretty bad experience.

That wasn't what I was talking about. I'm talking about almost imperceptible, frame-or-two jitters that is the current state of Android on virtually any contemporary device. The top selling Android devices are all "buttery smooth" in the perception of their users, even if relative to an iPhone it is herky jerky.


I have iOS 4.3.x on my iPhone 3G and it stutters compared to iOS 3 at the same time. So much so that when I got my iPhone 4S I noticed how much the iPhone 3G lagged and stuttered that I no longer use it, even as a simple iPod.


Fair enough, I haven't tried Android on a more recent device so my experience is certainly out of date. But when there are this many people saying there's a problem, surely it would make sense - especially for a fundamentally data-driven company like Google - to do some user studies and quantify it? I haven't heard of any such studies though; do you (or anyone else) know of any?


Perhaps. But once the end user notices the lag compared to their friends device, it very quickly becomes an end users (and very shortly, the platforms) problem. My android lags, and it pisses me off.

per your quote: "It's the same as getting an upgrade to your PC, a new video card, etc. You were perfectly happy before, but relative to your new reality the old one seems subpar, and you overestimate how much it interferes with your enjoyment of the device." Doesn't quite make sense in this market though. It's all about having the fastest, shiniest, device. And if you can't keep up or deliver ever demanding performance increases, you die. If good was good enough, and we didn't care that the next best thing was only marginally better, we'd still be using punch cards.


> t's all about having the fastest, shiniest, device. And if you can't keep up or deliver ever demanding performance increases, you die.

It's not even about that. It's about something usable and working as expected. I have an Android smartphone (LG P350) with bundled Facebook and Twitter, both of which I never use because they're too heavy for the phone. They barely work, they hang up for minutes, and crash my homescreen. And if I try to sync them, it usually ends with me taking the battery out after few minutes of staring at shining screen of a totally non-responsive (hardware buttons included) phone. Not to mention that once or twice an incoming call was too heavy for that phone to handle, => battery removal operation necessary.

Next time before choosing Android, I'll carefully test current devices, and switch to iPhone if I ever find a trace of UI lag.


I don't disagree with what you've written, and the relative thing is a problem -- if people feel a bit shameful that their new device isn't as slick as the last generation iPhone, it does hurt love of one's device a bit. That's why Android 4.0 takes big steps in the "be proud to show it off" realm.

However to the relative thing, to most smartphone users the things that matter are can I use Facebook, how is the picture quality, can I share videos, etc. Others want a keyboard, big and bright screen, etc. To normal users -- the ones buying the overwhelming bulk of devices -- this just isn't the big issue that it is on tech boards. It just isn't.


I disagree here based on interacting with someone who owns an ipad v1. When this person tried out my samsung honeycomb tablet, she thought it was slower "computer" that hers, even though she's doesn't know the specs of my "dual-core" honeycomb tablet.


This is why Apple is right to not talk about specs. It doesn't matter what your specs are if your actual device is slower.


Not quite. For instance, on a Galaxy S II, going to the home screen while in the mail app takes ~2 seconds. Doesn't matter how many times I do it, or even if I just do it in a loop, switching between mail and home. It's probably not even Android's direct fault - I wouldn't be surprised if this is Samsung's horrible software shining through - but it's very frustrating, and I don't use other devices to compare it to.


It's a digression (and an apples-to-oranges one at that) but your experience is definitely not typical. I have a Samsung Epic (Sprint's Galaxy S variant) running their new EI22 Gingerbread stack (very likely the same userspace base you have). And I don't see this at all. I don't use the built-in mail app, preferring K9. And I don't use the default home screen (Launcher Pro is just plain better). But the transition to the home screen is always instantaneously animated. Certainly nothing like 2 seconds.

So I'd put that up to a plain old bug (albeit a really frustrating one, and knowing the Android ecosystem one unlikely to be fixed), not a platform misfeature.


A big part of the delay on the GS II is the Vlingo voice functionality. Did you know (I ask because many people don't know) that if you tap the home button twice it brings up voice mode? The ability to recognize double clicks imposes a certain floor on the responsiveness of that button.

That most certainly does bother me, and I've yet to discover how to disable it so it simply reacts immediately.


Why should it? The iPhone uses a home double-click to pull up the task manager/switcher interface. Yet single clicking the home button still instantly gives you the response you expect.


I get a consistent slight delay on the iPad. Nothing really long (maybe 500ms?) but if I pay attention I can definitly notice it.


>Yet single clicking the home button still instantly gives you the response you expect.

The task manager/switcher is a child of the home screen. This overloaded functionality makes sense that you go to the home screen immediately and if you happen to click again it goes to the secondary mode.

Vlingo on the GS II has nothing to do with the home screen. It is its own world.

Should they have made the very first click instantly go to the home screen anyways (which could involve a lot of busy work given how rich an Android homescreen can be)? Good question. I don't think the two are directly comparable however.


Yea, I hate that. It comes up by accident all the time. Good point that it could be delaying it. Samsung incompetence.


> If you are a developer or a reviewer and you regularly use an iOS device and an Android device, the difference is evident and jarring. If you're an end-use it quickly disappears and is a non-issue. It just isn't a real problem for end users.

Except when they're trying out different devices looking to buy one.

Also, to a certain extent people put up with stuff like this because they don't know it can be better. E.g. Windows's shitty move/resize for all those years. But do you think, in the face of OS X, Windows could've continued to do without compositing up to now?


> If you're an end-use it quickly disappears and is a non-issue. It just isn't a real problem for end users.

Yes, it is. When people ask me how I like my new smartphone, I always say to them: "I like the idea behind Android, but it sucks in use; this smartphone is too weak to handle the basic OS, which makes using it terribly annoying for most of the time".

Yes, it sucks. There are constant lags in everything from button presses to scrolling. Main screen gets killed by the OS every few minutes, and it takes it 30 seconds to load up and become usable. Activating Wi-Fi and letting Facebook and GMail sync at the same time equals to several-minute long hang followed by me plugging the battery out. The phone occasionally hangs when receiving calls, and often when trying to dial.

Yes, for me, Android phones are piece of crap. I use mine, I put up with it, but it's not pleasant. It's damn annoying every single day.


Even my 1st generation HTC Magic+ had an experience absolutely nothing like what you've described. I don't know what sort of broken device you're in possession of, but it has nothing to do with Android. What is being described generally are trivial framerate deviations while animating the UI, not "30 second" pauses.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: