Friday, November 12, 2010

Using Time Profiler to Tune Performance

There are two parts of software development on the iPhone we still don't feel comfortable with: gdb and Instruments. We know they are powerful tools but we just can't seem to understand what they are telling us most of the time. Perhaps understanding those two areas of development is a good goal for the next quarter. If we knew those tools we would be able to write better software, faster.

Here is an example of Instruments in action tonight. We
are trying to speed up an application that just seems sluggish. Especially on our older test devices. Our philosophy is to always test on the oldest devices we have. If it runs well on those, it will fly on newer hardware.

We ran the app with just the Time Profiler so we could identify where the app spends its time. Some of the things were obvious to us. However, here was one that wasn't obvious and turns out was a simple fix on our part with a high return.

This particular application streams audio using a set of co
de written by Sound Cloud to interface with their site. We noticed, however that the NSDateFormatter was taking a great deal of time:
4.9% of the time had been spent regenerating a date formatter object. With a little digging we found this set of code:

NSDate *position = [NSDate dateWithTimeIntervalSinceReferenceDate

:stream.playPosition / 1000.0];

NSDate *songEnd = [NSDate dateWithTimeIntervalSinceReferenceDate:[currentArticle.duration intValue] / 1000.0];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;

[formatter setDateFormat:@"mm:ss.S"];

playPositionLabel.text = [NSString stringWithFormat:@"%@ / %@", [formatter st

ringFromDate: position], [formatter stringFromDate:songEnd]];

scrubberSlider.maximumValue = (float)[currentArticle.duration intValue];

scrubberSlider.value = (float)stream.playPosition;

We were alloc/initting an NSDateFormatter every 2/10's of a second, then using it to display some numbers and then throwing it away. It seemed harmless enough but clearly the whole alloc/init was more overhead that we realized. So, we simply moved the variable out and declared it in the header file as a regular variable

NSDateFormatter *formatter;

and then just set it up in the viewDidLoad method

formatter = [[NSDateFormatter alloc] init] ;

[formatter setDateFormat:@"mm:ss.S"];

Now it should be alloc/initted just once and then used each time. Sure enough we ran again and now we had to actually search for the references to the NSDateFormatter since they were so far down the list.


Thursday, November 4, 2010

Writing Apps for the iPad

The recent PBS app for the iPad got a lot of press and we, like many others, downloaded it. So far it hasn't quite been what we expected from the reviews. Today we were greeted with this error.

A PBS application that cannot play videos isn't going to be very useful to us. Sadly, as people are rushing to stake out their portion of the iPad/iPhone space we are seeing things like this more often.

We can imagine that PBS, like lots of Enterprises before them, saw the new application as a great thing but didn't understand that regular monitoring and updating of their new system would be needed. Or else, they went outside of their normal workflow processes to get the initial application populated but then did not set up ongoing processes to ensure that future media was ready for this new channel.