Draw text faster with CGContextShowTextAtPoint

The FindIt puzzles have turned out pretty well, but there are still a few things I am not happy with. The things that bother me most--slow load times on the puzzle selection page and on the puzzle screen. The load time on the puzzle selection page is not horrible--usually 2 to 3 seconds. But my goal is to release an update to FindIt Premium that will include all the puzzle packs to date. If I am seeing 2-3 seconds for 10 puzzles, what will it be like at 30? This clearly needs to be improved.

Luckily, this part was easier to figure out. To get the game out the door, I used text files for the data. With some time to step back and get the game cleaned up, I changed the puzzle metadata over from flat files to SQLite and Core Data. This has had a small impact on load time--around 2 seconds. Not that significant for just 10 puzzles, but in my profiling, and I seeing a significant increase as the number of puzzles increases. So my update for this should be coming out soon.

But what about the main page load time? Again, I performed some analysis to determine what was the bottleneck. I had assumed loading the page data from files again was the problem. So I started commenting out code and testing. Sure enough, the puzzle data loaded very quickly from a single file. That wasn't it.

Next I tried changing my looping logic, changed from a dynamically allocated NSMutableArray to an array I preallocated to the correct size, and even changed my short-cutting logic to decide whether to write out a letter or not. None of these were the culprit.

But then I commented out my writing the letters to the screen with NSString drawInRect. Immediately, even my largest puzzles (85x85) loaded in a second. So I set out to find a more efficient way to write out text. As I learned more, I saw that drawInRect is really trying to do a lot for you--like using the output area of the text for alignment and clipping. I am just trying to write out a single letter, so this was all unnecessary overhead.

If you are doing something like this, try CGContextShowTextAtPoint. This is a much more high-performance function that is not trying to align the text or perform clipping--it is just writing out the letters the way you tell it to. For me, this was perfect, and much more efficient. I noticed load time on even the largest puzzles was much more efficient, around 2 seconds or so, down from as many as 5.

This is also good news since I plan to release an iPad version of FindIt. Sure, the processor is going to be faster, but I also plan to display a lot more on a page. Considering that, I wanted to be sure to have the efficiency tweaked for optimal performance.

Hopefully this helps you too! Good luck with your iPhone and iPad development!


Post a Comment