This blog post has been going viral for the past weeks in iOS community. It talks about potential iOS performance optimisations, backed by sound technical argument.
One of the optimisations talks about
UITableViewCell/UICollectionViewCell. You can read the original blog for detail, but here is the gist :
UILabelis just a bitmap. Thus, it is more costly than you would think.
- It is even more costly when the
UILabelcannot be rendered in monochrome, e.g., using
- It could save you megabytes by nilifying labels’ text when you don’t need them. (Specifically in
So, just for fun, I decided to run some tests to get my own feeling about it.
My setup is very simple. I created a simple table view application with one label in each cell. In order to see the effect of memory, I made the text pretty long. Like this :
Switching on “Nil out …” switch will run the advice to nilify the text in
tableView(_:didEndDisplaying:forRowAt:) . “Attributed labels” switch will change the labels text to
attributedTextin red color.
I ran my program on Instruments and measured how much the resident memory (physical memory consumption) changed after scrolling all the way down. As advised in the original article, I “Simulate Memory Warning” before reading the actual/stable number.
In the above example, with simple
UILabel (no attributed text) without any optimisation, it started with 6.34MB before scrolling, ended with 6.59MB after scrolling. So, the action of showing the entire contents of the table and coming back to the original state caused 0.25MB (250KB) increase in physical memory footprint.
I ran the experiment with
UILabelwithout any optimisation
UILabelwith nilifying optimisation
attributedTextwith nilifying optimisation
A note is that I did it just for fun to get a ball park feeling myself, so I didn’t make stats. The results are just from a single run.
Here are the results :
Indeed nilify takes some effect, but not by much. The sample code has 192 rows, and the difference is mere 40KB~230KB. What surprised me was that Attributed Label didn’t increase memory foot stamp by much 🤔
What I tried next was to actually cache all the labels as in the following code:
It is definitely an anti-pattern that throws away the benefit of cell reuse that
UITableView offers. But 1. I have seen such code before 2. I wanted to see how much actually the ~200
UILabel instances contribute to the memory footprint.
The result is as follows (New results are row 3 and row 6):
Here again, Attributed Label makes it bigger, but not by much 🤔 But it’s fair to say that ~200
UILabels increased the memory footprint more than 5MB (~25KB per label). Is it bigger or smaller than you expected?
Next, I tried to bring in
UIImageView for comparison. I created exactly same table views with
UIImageViews of similar size as the
UILabels we implemented before:
And ran the same experiments (New results are in the bottom 3 rows):
UIImageViews, the cell reuse mechanism clears the memory very well, so you don’t have to worry about memory increase at least in this case. If we cache
UIImageViews, then it will increase almost 8MB of memory with ~200 images (~40KB per image), so it is a big deal. The memory footprint difference between
UIImage(~40KB) would have looked too small for my naive eyes if I didn’t know that
UILabel is stored as bitmap internally. But the difference between monochrome and color of
UILabel was not very visible in my experiment 🤔
UILabeldoes probably not take any effect on simple cases like this. (and probably for many complex cases as well)
- As described in the original article,
UILabelinternally may occupy more memory than you would expect
- Caching contents of the
UITableView/UICollectionViewis very bad for memory :D
- My code for this experiment is located in [github].