Memory Management with NSDecimalNumber: How to avoid memory problems in tight loops?

只愿长相守 提交于 2019-12-23 06:57:27

问题


I have a tight loop that iterates about 500 times. In every iteration, it will create a few NSDecimalNumber objects to do some arithmetics.

Example - this code snippet is in the for loop. the -decimalNumberByAdding: method creates a new NSDecimalNumber instance and autoreleases it.

resultDecimalNumber = [resultDecimalNumber decimalNumberByAdding:anotherDecimalNumber];

So let me get that right: If the loop is huge, I collect thousands of NSDecimalNumber objects which wait for the whole loop to finish and the method to return, in order to get autoreleased after long time waiting.

How could I prevent a memory overflow? I've always tried to use non-autoreleased objects, but in this case it seems I have to live with them.

Imagine this was my loop:

for(i=0, i<500, i++) {
    resultDecimalNumber = [resultDecimalNumber decimalNumberByAdding:anotherDecimalNumber];
}

What would I have to add there? Must I create a autorelease pool inside the loop and drain it? Would that make sense?


回答1:


Yes. You should create your own autorelease pool inside the loop. This is exactly the situation that nested autorelease pools are for.




回答2:


Use the C struct NSDecimal. From Apple's "Number and Value Programming Topics for Cocoa":

You might consider the C interface if you don’t need to treat decimal numbers as objects—that is, if you don’t need to store them in an object-oriented collection like an instance of NSArray or NSDictionary. You might also consider the C interface if you need maximum efficiency. The C interface is faster and uses less memory than the NSDecimalNumber class.

If you need mutability, you can combine the two interfaces. Use functions from the C interface and convert their results to instances of NSDecimalNumber.

I use NSDecimal, rather than NSDecimalNumber, on the iPhone for this very reason. You get all the precision of NSDecimalNumber, with a lot less overhead.

Benchmarking the two on my Mac (MacBook Air, 2nd gen), gives these results:

NSDecimal
Additions per second: 3355476.75
Subtractions per second: 3866671.27
Multiplications per second: 3458770.51
Divisions per second: 276242.32

NSDecimalNumber
Additions per second: 676901.32
Subtractions per second: 671474.6
Multiplications per second: 720310.63
Divisions per second: 190249.33

Even ignoring the memory usage, you get a near fivefold speedup in every operation but division if you use NSDecimal and the C APIs.




回答3:


You can get the builtin floating-point equivalents for the NSDecimalNumbers you are using, then cast the result back into an NSDecimalNumber at the end of the loop:

double total(0);

for (i = 0; i < 500; ++i)
{
    total += [anotherDecimalNumber doubleValue];
}

resultDecimalNumber = // turn total back into an NSDecimalNumber

This technique will not only save you heaps of memory allocations inside the loop, but will also be significantly faster because you'll be using on-chip math operations instead of firing off functions.



来源:https://stackoverflow.com/questions/1336083/memory-management-with-nsdecimalnumber-how-to-avoid-memory-problems-in-tight-lo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!