b2cloud

13th December 2013

Obj-C performance week 2: Numbers to strings

Thoughts By 3 years ago

In this weeks performance comparison I will be comparing convering a number to a string.

There are two common ways of doing this.

NSNumber’s stringValue

This method involves first turning your primitive number type into a obj-c wrapped type of NSNumber, then calling it’s stringValue method to get a string representation of the number.

NSString’s initWithFormat:

Using initWithFormat:, the type of the number must be known, and then can be converted using a format such as @”%d” (integers) or @”%f” (floats) etc etc.

The results

initWithFormat: is clearly better in terms of performance…

Explanation

At first this was surprising for me. How could it be that a method on NSNumber yields slower results compared to using the number with a format string? I turned to the time profiler to find out. I found that NSNumber‘s stringValue method still uses initWithFormat: under the hood, meaning there’s slight overhead from determining the datatype, then figuring out which format to use. Of course if you manually specify a format string then this doesn’t need to happen, and things may be quicker.

However, the trade off of manually using a format string with initWithFormat: is that you must know the primitive value’s type. This can be a pain especially when Mac and iOS went from 32 bit to 64 bit, when an NSUInteger went from an unsigned int to an unsigned long depending on which architecture you were compiling for. Considering this, I still personally prefer using the NSNumber method.

If you are a speed freak, then look past both of these and instead try sprintf() or one of it’s similar functions.

The code

If you want to run the same tests, my code is as follows. Done 3 million times to separate each test by mere milliseconds.

#define TEST_NSNUMBER 1
#define TEST_FORMAT 2

#define TEST TEST_FORMAT

const CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();

for(NSUInteger i = 0; i < 3000000; i++)
{
#if TEST == TEST_NSNUMBER
	NSString* result = @(42).stringValue;
#elif TEST == TEST_FORMAT
	NSString* result = [NSString stringWithFormat:@"%d", 42];
#endif
}

const CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();

NSLog(@"%f seconds", end - start);
Recommended Posts

Making iOS apps Universal

Post by 3 years ago

Turning your old iPhone or iPad app into a Universal app that natively supports both devices is fairly easy, as long as you know where to look and what to change. To clear confusion here

Got an idea?

We help entrepreneurs, organizations and established brands from around
the country bring ideas to life. We would love to hear from you!