I work on an iPad application that has a sync process that uses web services and Core Data in a tight loop. To reduce the memory footprint according to Apple\'s Recomendatio
Note that ARC enables significant optimizations which are not enabled at -O0
. If you're going to measure performance under ARC, you must test with optimizations enabled. Otherwise, you'll be measuring your hand-tuned retain/release placement against ARC's "naive mode".
Run your tests again with optimizations and see what happens.
Update: I was curious, so I ran it myself. These are the runtime results in Release mode (-Os), with 7,000,000 allocations.
arc-perf[43645:f803] outer: 8.1259
arc-perf[43645:f803] outer: 8.2089
arc-perf[43645:f803] outer: 9.1104
arc-perf[43645:f803] inner: 8.4817
arc-perf[43645:f803] inner: 8.3687
arc-perf[43645:f803] inner: 8.5470
arc-perf[43645:f803] withGoto: 7.6133
arc-perf[43645:f803] withGoto: 7.7465
arc-perf[43645:f803] withGoto: 7.7007
arc-perf[43645:f803] non-ARC: 7.3443
arc-perf[43645:f803] non-ARC: 7.3188
arc-perf[43645:f803] non-ARC: 7.3098
And the memory peaks (only run with 100,000 allocations, because Instruments was taking forever):
Outer: 2.55 MB
Inner: 723 KB
withGoto: ~747 KB
Non-ARC: ~748 KB
These results surprise me a little. Well, the memory peak results don't; it's exactly what you'd expect. But the run time difference between inner
and withGoto
, even with optimizations enabled, is higher than what I would anticipate.
Of course, this is somewhat of a pathological micro-test, which is very unlikely to model real-world performance of any application. The takeaway here is that ARC may indeed some amount of overhead, but you should always measure your actual application before making assumptions.
(Also, I tested @ipmcc's answer using nested for loops; it behaved almost exactly like the goto
version.)
The following should achieve the same thing as the goto
answer without the goto
:
for (NSUInteger count = 0; count < MAX_ALLOCATIONS;)
{
@autoreleasepool
{
for (NSUInteger j = 0; j < BATCH_SIZE && count < MAX_ALLOCATIONS; j++, count++)
{
NSString *text = [NSString stringWithFormat:@"%u", count + 1U];
[text class];
}
}
}