使用NSDecimalNumber进行内存管理:如何避免紧密循环中的内存问题?

时间:2009-08-26 16:46:26

标签: iphone cocoa-touch memory-management uikit

我有一个紧凑循环,迭代大约500次。在每次迭代中,它都会创建一些NSDecimalNumber对象来做一些算术。

示例 - 此代码段位于for循环中。 -decimalNumberByAdding:方法创建一个新的NSDecimalNumber实例并自动释放它。

resultDecimalNumber = [resultDecimalNumber decimalNumberByAdding:anotherDecimalNumber];

所以让我做对了:如果循环很大,我会收集数千个等待整个循环完成的NSDecimalNumber对象和返回的方法,以便在等待很长时间后自动释放。

如何防止内存溢出?我一直试图使用非自动释放的对象,但在这种情况下,似乎我必须忍受它们。

想象一下这是我的循环:

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

我必须在那里添加什么?我必须在循环内创建一个自动释放池并将其排干吗?那会有意义吗?

3 个答案:

答案 0 :(得分:3)

使用C结构NSDecimal。来自Apple的"Number and Value Programming Topics for Cocoa"

  

您可以考虑使用C接口   你不需要处理小数   数字作为对象 - 也就是说,如果你   不需要将它们存储在一个   面向对象的集合就像一个   NSArray或NSDictionary的实例。   你也可以考虑C   如果你需要最大的接口   效率。 C接口更快   并且使用的内存少于   NSDecimalNumber类。

     

如果你需要可变性,你可以   结合两个接口。使用   来自C接口的函数和   将他们的结果转换为实例   NSDecimalNumber。

出于这个原因,我在iPhone上使用NSDecimal而不是NSDecimalNumber。您可以获得NSDecimalNumber的所有精度,而且开销更低。

在我的Mac(MacBook Air,第二代)上对两者进行基准测试,得出以下结果:

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

即使忽略了内存使用情况,如果你使用NSDecimal和C API,你在每个操作中都会获得近五倍的加速,但除非分区。

答案 1 :(得分:1)

是。您应该在循环内创建自己的自动释放池。这正是嵌套自动释放池的用途。

答案 2 :(得分:-1)

您可以获取正在使用的NSDecimalNumber的内置浮点等价物,然后在循环结束时将结果转换回NSDecimalNumber

double total(0);

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

resultDecimalNumber = // turn total back into an NSDecimalNumber

这种技术不仅可以在循环中节省大量的内存分配,而且还会明显加快,因为你将使用片上数学运算而不是触发函数。