Reduce Peak Memory Usage With @autoreleasepool

后端 未结 2 1081
挽巷
挽巷 2020-12-28 23:23

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

相关标签:
2条回答
  • 2020-12-28 23:55

    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.)

    0 讨论(0)
  • 2020-12-29 00:13

    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];
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题