13 ms·
Why is the mobile web slow?
- chrisdevereux 13y ago> Don't allocate when you need fast performance. This is good practice regardless of whether you are using a GC since allocation/deallocation of memory are slow operations (in fact game programmers NEVER allocate during game level execution). > 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. The GC is unlikely to kick in and your performance will be predictable and fast. ARC on the other hand doesn't allow you to do that since ARC instantly deallocates an object you finished working with. I don't understand this. All the strategies one might use to avoid allocations in performance-critical code under GC (pooling resources, or whatever) are also available under ARC. The difference is that if the way I use memory causes performance issues without GC, it will be much more reliably reproducible than with GC.
- Roboprog 13y agoGreat, I gotta write (as if) in FORTRAN :-)
- chrisdevereux 13y agoHey, I said "might"!
- invalidname 13y agoThat's true. The article however, does state that a GC stall is bad but explains it can be avoided with a good GC and a good programmer. With ARC you get more consistent performance but the article was going after the claim that GC inherently require 5 times more RAM to be reasonably performant.
- icoder 13y agoWouldn't cleanup in an ARC setup be more (or just as much) dependent on de-allocations (or actually reference loss) than allocations, while in a GC environment a freeup (albeit less predictable and of higher impact) is mostly triggered by deallocation? At least that's what I understood from the article.
- joeblau 13y agoSo I don't know much about anything, but I'm confused on this point. You say "This effectively means it always performs late binding and invoking a message is REALLY slow in Objective-C." But I can't find any evidence of Objective-C performing late binding or in documentation [1][2][3][4]. [1] - http://stackoverflow.com/questions/5943949/late-binding-vs-dynamic-binding http://stackoverflow.com/questions/5943949/late-binding-vs-d... [2] - http://www.gnu.org/software/gnustep/resources/ObjCFun.html http://www.gnu.org/software/gnustep/resources/ObjCFun.html [3] - http://developer.apple.com/library/ios/#documentation/general/conceptual/DevPedia-CocoaCore/DynamicBinding.html http://developer.apple.com/library/ios/#documentation/genera... [4] - http://stackoverflow.com/questions/9470824/dynamic-binding-late-binding-in-java-or-not http://stackoverflow.com/questions/9470824/dynamic-binding-l...
- invalidname 13y agoThe original article seemed to have a mistake there, it now says dynamic binding. This is indeed much slower than regular invocation as the first article you linked to states.
- Roboprog 13y ago"Late binding" is a generalized term for associating a symbol with a value/code at run time, instead of compile/link time. (even if the term is not literally used in the obj-C docs)
- kybernetyk 13y ago> 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 cached and for every subsequent call the cache is used. Then there's some real neat trickery that is performed in objc_msgSend() ... after the method to "call" has been found the code directly jumps into that method without creating a new stack frame. (All needed arguments have been passed to objc_msgSend() and are already on the stack.) objc_msgSend() in essence is a trampoline. 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. Performance Numbers: http://www.mikeash.com/pyblog/performance-comparisons-of-common-operations-leopard-edition.html http://www.mikeash.com/pyblog/performance-comparisons-of-com... More about objc_msgSend(): http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-build-objc_msgsend.html http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-buil... Now I don't know enough about Java but I guess it isn't much more faster than that. So calling Obj-C slow may be a little too bold.
- invalidname 13y agoMaybe this Objective-C optimization isn't implemented in iOS: http://www.shannah.ca/blog/?p=226 http://www.shannah.ca/blog/?p=226
- kybernetyk 13y agoIt 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.
- asveikau 13y agoTrampolining 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.
- mr_luc 13y agoThe 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).
- kalms 13y agoHere's the first few hits from Google: https://developers.google.com/speed/articles/reflow https://developers.google.com/speed/articles/reflow https://developers.google.com/speed/articles/javascript-dom https://developers.google.com/speed/articles/javascript-dom http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/ http://www.stubbornella.org/content/2009/03/27/reflows-repai...
- ohwp 13y agoMaybe this will help: https://developers.google.com/speed/articles/reflow https://developers.google.com/speed/articles/reflow Edit: ah, posting the same link at the same time... But I think the best tip is: be shallow. A lot of things trigger reflow but DOM-depth is causing slow reflows.
- deleted 13y ago[deleted]
- Supermighty 13y agoWould doing a majority of the reflow work on a canvas element help with speed?
- dmethvin 13y agoI'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.
- dougk16 13y ago"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 completely within one function. You have to watch out for some gotchas like recursing into the same function, but overall it's a pretty painless and clear pattern for me. Multiple functions can all share the same static memory too. Not that I'm religious about this design pattern, but it's something I try to do in performance-critical code.
- CountHackulus 13y agoJava does this a whole bunch, it's decently easy for compiler writers to implement and it gets a good speedup on most benchmarks.
- rsynnott 13y agoGood Java JIT environments (HotSpot etc) do this. It looks like Dalvik does not.
- pjmlp 13y agoFrom 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.
- Zigurd 13y agoIt'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.
- rsynnott 13y ago> 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...
- fpgeek 13y agoAh, 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...
- rsynnott 13y agoYou 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).
- Dylan16807 13y agoA nightmare? Is it hard/impossible to wrap the allocation function with a boolean check and a spin in ObjC?
- FelixH 13y agoIt feels like the author just hijacked the topic to rant about Objective-C. No big insights into why web apps are slow other than: javascript is not the bottleneck, rendering the dom (which is a complicated process) is.
- crazygringo 13y ago> 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).
- tg3 13y agoThis is where Web Workers [1] come in. You shouldn't be performing background processing in a way that blocks the UI. Heavy lifting like that should be pushed into the background, if it's done on the front-end at all. [1] https://en.wikipedia.org/wiki/Web_Workers https://en.wikipedia.org/wiki/Web_Workers
- st3fan 13y agomessage 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.
- est 13y agoThis is why http://widgetsandshit.com/teddziuba/2008/09/a-web-os-are-you-dense.html http://widgetsandshit.com/teddziuba/2008/09/a-web-os-are-you...