Live data from Hacker News

Why is the mobile web slow?

codenameone.com

31–40 of 48 posts

Re: Why is the mobile web slow?

#31

Earlier quoted context omitted.

Maybe this Objective-C optimization isn't implemented in iOS: http://www.shannah.ca/blog/?p=226

It really isn't that big of a deal. Trampolining is pretty straight forward and a caching of memory addresses isn't a big deal either. So I don't know why Apple wouldn't add this optimization to the iOS obj-c runtime.

Trampolining is harder to do if you keep around this absurdity (sorry "security feature") of not being able to mark pages as executable. If they open this up for the objc runtime then any other code in the same process would be able to do it too.

Re: Why is the mobile web slow?

#32

> Objective-C doesn't use methods like Java/C++/C#, it uses messages like Smalltalk. This effectively means it always performs late binding and invoking a message is REALLY slow in Objective-C. Well, "always" is a little wrong. The first time a message is passed and the bound method is called by the runtime is significantly slower (~4x slower than a virtual method call in C++). But then this message/method pair gets…

> So when sending a message to an object multiple times you only pay for the cache lookup - which is pretty fast by itself and a cached call is faster than a C++ virtual method call.

This is not true. The code in Mike's test for "IMP-cached message send" doesn't match the cached path of objc_msgSend. It matches what you would get by doing IMP-caching yourself, which is common in some Objective-C frameworks, especially older ones. The cached path of objc_msgSend is what is measured by the "Objective-C message send" row, which is a lot slower.

The fast path of objc_msgSend roughly goes like this: you dereference the isa of the object to get to a class description, then you dereference a pointer to the cache, and after finding the selector in the cache, perform a tail indirect call to the IMP. Even if the cache lookup is free this is two dependent pointer dereferences followed by a dependent indirect branch.

A C++ virtual call just dereferences a vptr and makes an indirect call to a function at a static index in the vtable, which will always be more efficient than objc_msgSend. It's true that manually caching the IMP yourself and calling it will be faster than a C++ virtual call, but there's nothing stopping you from caching the implementation of a C++ virtual call in exactly the same way.

Another major factor in the performance difference between C++ and Objective-C is that C++ allows you to have non-virtual member functions, which can be inlined, whereas Objective-C requires all method calls to go through the same mechanism.

Re: Why is the mobile web slow?

#33

Earlier quoted context omitted.

It really isn't that big of a deal. Trampolining is pretty straight forward and a caching of memory addresses isn't a big deal either. So I don't know why Apple wouldn't add this optimization to the iOS obj-c runtime.

Trampolining is harder to do if you keep around this absurdity (sorry "security feature") of not being able to mark pages as executable. If they open this up for the objc runtime then any other code in the same process would be able to do it too.

You're assuming writable trampolines. objc_msgSend()'s trampoline works by caching the target lookup and having an extremely short fast-path in the case that the target method implementation is cached.

objc_msgSend is a trampoline in the sense that it leaves the frame/registers untouched and jumps straight to the target implementation.

That said, you can implement the kinds of trampolines you're referring to without writable code pages, it just requires more work: http://landonf.bikemonkey.org/2011/04/index.html

Re: Why is the mobile web slow?

#34
post #6

The takeaway I got from this: DOM reflows are the major unsolvable source of perceived slowness. Cool. So, in an app where you avoid reflows, is mobile web fast? Why or why not? How avoidable are reflows? Can anyone point me to any articles that talk about this specifically, or benchmarks that make this concrete? (I vaguely recall benchmarks that covered reflow, but it's a vague memory).

I'd agree that some of the causes are unsolvable if you want a design completely unconstrained by the performance limits of HTML rendering environments. This is why some people build HTML apps that look like some native app they had and say, "this is too slow!" However, there are some very bad anti-patterns that cause unnecessary reflows, and those can be avoided if you understand them.

For example, many infinite-scroll pages add a small amount of content to the DOM and then ask, "Did I fill the page enough?" by asking for the new height of the page. Each time they do that it requires a reflow where the browser recalculates the height of the page. When the added content is small it may take four or five trips through this loop to feed enough content into the page. A better alternative performance-wise would be to make each chunk of added content a fixed height. That way it's easy to do the math inside your own code, add four or five chunks, and the browser will do a single reflow at the end.

If you look at the "flat" designs that are becoming common in operating systems and apps, they perform well in these situations because they are very regular and easy to compute. Things like rounded corners, transparency, and drop shadows all make pages slower to render.

Re: Why is the mobile web slow?

#35

> Objective-C doesn't use methods like Java/C++/C#, it uses messages like Smalltalk. This effectively means it always performs late binding and invoking a message is REALLY slow in Objective-C. Well, "always" is a little wrong. The first time a message is passed and the bound method is called by the runtime is significantly slower (~4x slower than a virtual method call in C++). But then this message/method pair gets…

Java can inline many of virtual calls, making them essentially as fast as static methods (= much faster than C++ virtual methods).

Java implementations can ....

The language alone cannot do anything.

Re: Why is the mobile web slow?

#36
post #9

"They can also reallocate elements into the stack frame rather than heap when they detect specific allocation usage." I've always been interested in whether this is done in various managed languages. Since I never know the answer, one pattern I've taken to is to allocate memory in static const/final fields that I would normally put on the stack in C, instead of doing a heap allocation to a variable whose scope is com…

Good Java JIT environments (HotSpot etc) do this. It looks like Dalvik does not.

From the few times I tried to read Android code, I think the JIT is not touched since Android 2.3.

I am still curious what Google is going to do with Java and Dalvik, as the whole thing seems to be frozen since the whole process with Oracle, and they only add new APIs.

The last two Google IOs did not have any Dalvik related talk.

Re: Why is the mobile web slow?

#37
> In fact JavaScript can't technically perform slowly since it is for most intents and purposes single threaded... so long running JavaScript code that will take 50 seconds just won't happen...

It's a valid point that almost nobody's writing 50-second raytracing routines in JavaScript, but it's trivial to run code that's executed in the background without freezing your app, by repeatedly calling it with setTimeout(). Just make sure that any "tick" of your code runs in under 30ms or so (although, depending on your task, that may not be so trivial).

Re: Why is the mobile web slow?

#38
message is REALLY slow in Objective-C

Some numbers to back this up would be nice. Apple has been optimizing the hell out of Objective-C and I think it has a method invocation down to like 10 instructions or so.

Re: Why is the mobile web slow?

#39
post #30

> This isn't really hard, you just make sure that while you are performing an animation or within a game level you don't make any allocations. That seems like a big 'just', at least in a multi-threaded application...

Ah, but if you're going to talk about multi-threaded applications, we're going to have to start talking about things like thread-safe reference counts...

You certainly have to be careful passing data between threads in ObjC (though, of course, you do in Java, too); the real problem with managed memory in multi-threaded highly latency sensitive UI applications, though, is that a thread other than the UI thread can happily trigger a stop the world collection through allocation, and it's very difficult for the UI thread to say "I'm doing something important for now; please don't allocate for a bit" (it's possible, but it's a nightmare).

Re: Why is the mobile web slow?

#40
post #36

Earlier quoted context omitted.

Good Java JIT environments (HotSpot etc) do this. It looks like Dalvik does not.

From the few times I tried to read Android code, I think the JIT is not touched since Android 2.3. I am still curious what Google is going to do with Java and Dalvik, as the whole thing seems to be frozen since the whole process with Oracle, and they only add new APIs. The last two Google IOs did not have any Dalvik related talk.

It's unclear if Dalvik's JIT compiler needs updating. For non-mobile uses like GoogleTV, it might be worth making a much more aggressive JIT compiler, since battery use would not be an issue. Other than that, it seems like changes would have a small benefit, a large risk, and a very large testing burden.

Android is, still, a very lean project inside and lean corporate structure. If it's a third of the way down the priority list, it probably ain't happening.

Post reply on HN