This is a very naive question, but I wonder if there is any comparison that can be made on paging or swapping speed? They are offering the same functionality (moving from memory to disk, etc) but with different strategies (writing frames, or writing down the whole memory). Now the problem is, can one of them be faster than the other? And what does this depend on?
Paging always happens. It's just a mechanism of mapping virtual memory. Swapping is "paging + disk I/O", so therefore no, paging is neither an alternative to swapping nor can be slower than swapping itself.
Related
In Android it is recommended that the view hierarchy depth be kept under 10, and strictly under 20 or else your app is very likely to perform poorly or crash (UI thread only a tiny 8-16kB of stack space)
Does this hold true for iOS, with or without autolayout (why or why not) ?
Views in iOS are backed by OpenGL and have amazing performance. I've personality gone as deep as 50 views with no problems. I don't recommend making the depth bigger than necessary, but when the situation calls for it, it is viable.
Update:
It is actually quite bad if you are using autolayout, as constraints solving has polynomial complexity (cassowary is linear in the sense that it solves linear equations)
http://floriankugler.com/2013/04/22/auto-layout-performance-on-ios/
http://pilky.me/36/
UIView itself is very fast as posts here suggest, however. I ended up replacing autolayout with an alternative system.
TLDR: UIView/CALayer is fast. Autolayout is not.
I've never seen any such recommendation for iOS. As always, you should implement your code and view hierarchy as straightforward as possible. After that, measure your performance and tweak if needed. Avoid premature optimization as much as possible.
I have a collection view that displays 3 images, two labels, and 1 attributed string(strings are of different colors and font sizes and values are not unique for every cell). One of the images is coming from the web and I used AFnetworking to do the downloading and caching. The collection view displays 15 cells simultaneously.
When I scroll I can only achieve 25 frames/sec.
Below are the things I did:
-Processing of data were done ahead and cached to objects
-Image and views are opaque
-Cells and views are reused
I have done all the optimizations I know but I can't achieve at least 55 frames/sec.
If you could share other techniques to speed up the re-use of cells.
I was even thinking of pre-rendering the subviews off screen and cache it somewhere but I am not sure how it is done.
When I run the app on the iPhone it is fast since it only shows at least four cells at a time.
The first thing you need to do is fire up instruments and find out if you're CPU-bound (computation or regular I/O is a bottleneck) or GPU-bound (the graphics card is struggling). . depending on which of these is the issue the solution varies.
Here's a video tutorial that shows how to do this (among other things) . . This one is from Sean Woodhouse # Itty Bitty Apps (they make the fine Reveal tool).
NB: In the context of performance tuning we usually talk about being I/O bound or CPU bound as separate concerns, however I've grouped them together here meaning "due to either slow computation or I/O data is not getting to the graphics card fast enough". . if this is indeed the problem, then the next step is to find out whether it is indeed related to waiting on I/O or the CPU is maxed-out.
Instruments can be really confusing at first, but the above videos helped me to harness its power.
And here's another great tutorial from Anthony Egerton.
What is the size of the image that you use?
One of the optimization technique which would work is that
Resize the image so that it matches the size of the view you are displaying.
I am adding multiple UIImageView to a UIView to perform operations such as drag,pinch and zoom images.I have added gesture recogniser to all the UIImageViews.Since i'm adding multiple images(UIImageViews) it has brought down the performance of my app.Does any one have a better solution to perform this? Thanks
The adding of many images should not generally, cause enough of a problem that your app would slow down. For example, to illustrate the point with an absurd example, I added 250 (!) image views each with three gestures, and it works fine on an iPad 3, including the animating of the images into their final resting place/size/rotation.
Two observations:
Are you doing anything computationally intensive with your image views? For example:
Simply adding shadows with Quartz 2D has a huge performance impact because it's actually quite computationally expensive. In the unlikely even that you're using layer shadows, you can try using shouldRasterize, which can mitigate the problem, but not solve it. There are other (kludgy) techniques for doing computationally efficient shadows if that's the problem.
Another surprising computationally intensive process is if your images are (for example) PNGs with transparency settings or if you have reduced the alpha/opacity for your views.
What is the resolution/size of the images being loaded? If the images are very large, the image view will render them according to the contentMode, but it can be very slow if you're taking large images and scaling them down. You should use screen resolution images if possible.
These are just a few examples of things that seem so innocuous, but are really quite computationally expensive. If you're doing any Quartz embellishments on your image views, I'd suggest temporarily paring them back and see if you see any changes.
In terms of diagnosing the performance problems yourself, I'd suggest watching the following two WWDC videos:
WWDC 2012 - #211 - Building Concurrent User Interfaces on iOS includes a fairly pragmatic demonstration of Instruments to identify the source of performance problems. This video is clearly focused on one particular solution (the moving of computationally expensive processes into the background and implementing a concurrent UI), which may or may not apply in this case, but I like the Instruments demonstration.
WWDC 2012 - #235 - iOS App Performance: Responsiveness is a more focused discussion on how one measures responsiveness in apps and techniques to address problems. I don't find the instruments tutorial to be quite as good as the prior video, but it does go into more detail.
Hopefully this can get you going. If you are still stumped, you should share some relevant code regarding how the views are being added/configured and what the gestures are doing. Perhaps you can also clarify the nature of the performance problem (e.g. is it in the initial rendition, is it a low frame rate while the gestures take place, etc.).
This topic was mentioned in my CS data structure class, but I didn't quit followed it. So wondering if anyone can spend a little time explain to me how that will work with sequential allocation in memory. It will be very helpful with a graph or some illustration that can help me understand it.
Also I am wondering if this can happen to two queues.
Thank you
I am assuming sequential allocation used here means a block of memory, without gaps.
One possibility is that this can be something like a deque (double ended queue), except this would be a double ended stack. So for example, you allocate a block of sequential memory that has enough memory for N elements, you would have a pointer to the "top" of the first stack, which would start at the first element and grow to the right. You would also have a pointer to the "top" of the second stack, which would start at the last element and grow left. If the two "tops" cross each-other, its time to "grow" the memory; reallocate and copy one or both stacks to the new spot. Thus each of the stacks can grow until both of their sizes together surpasses N.
Illustration (from here, a page discussing using such data structures as allocators):
With respect to queues, yes you create two queues out of this block, but it will potentially have an extra hole/gap, as the bottoms of the queues can move up (away from the ends). A possible solution to this would be, instead of popping off the front, one could empty the front element, and swap with the back, while keeping pointers to the actual front and back.
Hardware call stacks always grow in the same direction, but you could have two software stacks growing from opposite ends of an allocation. This seems trivial and cute, so it may not be what you're talking about.
I can already hear the wrenching guts of a thousand iOS developers.
No, I am not noob.
Why is -drawRect faster for UITableView performance than having multiple views?
I understand that compositing operations take place on the GPU. But compositing is a one-time operation; once the layers are committed to memory, it is no different from a cached buffer that, from the point of view of the GPU, gets translated in and out of view. Compare this to using Core Graphics in drawRect, which employ an unknown amount of operations on the CPU to produce pixels that end up getting cached in CALayers anyway. What's the difference if it all ends up cached and flattened anyway?
Also, if you're handling cell reuse properly, you shouldn't need to regenerate views on each call to -cellForRowAtIndexPath. In fact, there may be a performance benefit to having the state data (font, font size, text color, attributes, etc) cached by UIView/CALayer objects than having them constantly recreated during -drawRect.
Why the craze for drawRect? Can someone give me pointers?
When you talking about optimization, you need to provide specific situations and conditions and limitations. Because optimization is all about micro-management. Otherwise, it's meaningless.
What's the basis of your faster? How did you measured it? What's the numbers?
For example, no-op or very simple -drawRect: can be faster, but it doesn't mean it always does.
I don't know internal design of CA neither. So here are my guesses.
In case of static content
It's weird that your drawing code is being called constantly. Because CALayer caches drawing result, and won't draw it again until you send setNeedsDisplay message. If you don't update cell's content, it's just same with single bitmap layer. Should be faster than multiple composited layers because it doesn't need composition cost. If you're using only small number of cells which are enough to be exist all in the pool at same time, it doesn't need to be updated. As RAM becomes larger in recent model, it's more likely to happen in recent models.
In case of dynamic content
If it is being updated constantly, it means you're actually updating them yourself. So maybe your layer-composited version would also being updated constantly. It means it is being composited again for every frame. It could be slower by how it is complex and large. If it's complex and large and have a lot of overlapping areas, it could be slower. I guess CA will draw everything strictly if it can't determine what area is fine to ignore. Unlike you can choose what to draw or not.
In case of actual drawing is done in CPU
Even you configure your view as pure composition of many layers, each sublayers should be drawn eventually. And drawing of their content is not guaranteed to be done in GPU. For example, I believe CATextLayer is drawing itself in CPU. (because drawing text with polygons on current mobile GPU doesn't make sense in performance perspective) And some filtering effects too. In that case, overall cost would be similar and plus it requires compositing cost.
In case of well balanced load of CPU and GPU
If your GPU is very busy for heavy load because there're too many layers or direct OpenGL drawings, your CPU may be idle. If your CG drawing can be done within the idle CPU time, it could be faster than giving more load to GPU.
None of them is your case?
If your case is none of situations I listed above, I really want to see and check the CG code draws faster than CA composition. I wish you attach some source code.
well, your program could easily end up moving and converting a lot of pixel data if going back and forth from GPU to CPU based renderers.
as well, many layers can consume a lot of memory.
I'm only seeing half the conversation here, so I might have misunderstood. Based on my recent experiences optimizing CALayer rendering, and investigating the ways Apple does(n't) optimize stuff you'd expect to be optimized...
What's the difference if it all ends up cached and flattened anyway?
Apple ends up creating a separate GPU element per layer. If you have lots of layers, you have lots of GPU elements. If you have one drawRect, you only have one element. Apple often does NOT flatten those, even where they could (and possibly "should").
In many cases, "lots of elements" is no issue. But if they get to be large ... or there's enough of them ... or they're bad sizes for OpenGL ... AND (see below) they get stored in CPU instead of on GPU, then things start to get nasty. NB: in my experience:
"enough": 40+ in memory
"large": 100x100 points (200x200 retina pixels)
Apple's code for GPU elements / buffers is well optimized in MOST places, but in a few places it's very POORLY optimized. The performance drop is like going off a cliff.
Also, if you're handling cell reuse properly, you shouldn't need to
regenerate views on each call to -cellForRowAtIndexPath
You say "properly", except ... IIRC Apple's docs tell people not to do it that way, they go for a simpler approach (IMHO: weak docs), and instead re-populate all the subviews on every call. At which point ... how much are you saving?
FINALLY:
...doesn't all this change with iOS 6, where the cost of creating a UIView is greatly reduced? (I haven't profiled it yet, just been hearing about it from other devs)