如果我创建一个容量= 3而不是容量= 50的NSMutableArray,这有多重要?

时间:2009-08-20 21:12:29

标签: iphone cocoa-touch arrays uikit

我想知道这是否会影响性能或内存消耗。我需要一个NSMutableArray,并且在开始时我只能猜测将添加多少个对象。大概3到5个。所以我这样创建它:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:3];

在创建容量为3而不是50的情况下,这里究竟发生了什么?当知道至少有20个元素时,创建容量为1是不是一个坏主意?或者这不足以让人头疼吗?我在我的应用程序中有10个这样的数组,他们都必须在开始时加载。

5 个答案:

答案 0 :(得分:7)

initWithCapacity会导致NSMutableArray为该数量的元素预分配空间。

将更多数据推送到超出该容量的NSMutableArray将导致NSMutableArray重新分配其底层内存。这种重新分配还需要将整个阵列从旧(较小)分配复制到新(较大)分配。因此,对于使这个数字太小而存在性能损失,但不是很多。

指定一个大于实际使用容量的容量会浪费内存,因为将为永远不会使用的项目分配内存。

我的建议是,如果您知道阵列的大小通常不会超过N个项目,请致电initWithCapacity:N。偶然NSMutableArray大于N的性能损失是可以接受的,并且对于那些没有超过该限制的阵列而言,您将不必为此付出代价。

答案 1 :(得分:6)

除非你谈论极端重复或巨大阵列,否则这不是什么大问题。除非它成为真正的瓶颈,否则不值得尝试进行优化。

编辑:我想添加Donald Knuth的引用:

  

过早优化是万恶之源。

答案 2 :(得分:3)

有理论答案和实际答案。从理论上讲,设置更大的容量可能会改变阵列的分配和存储策略(虽然内部称为“NSArray”,但结构比这更复杂)。

从实际的角度来看,阵列将根据需要重新分配,并且您正在谈论的数字我怀疑会有任何不同。如果我知道我会把成千上万的物品放进去,我可能会做一个arrayWithCapacity .3对50基本没有意义。

从我的角度来看,“withCapacity”的最佳用途就是提供一个明显的钩子来挂起你的假设,所以你可以(例如)拥有你以后可能想要断言的东西的代码内文档。但这绝不是必需的。

从实际角度来看,最好地利用你的时间就是不要考虑这个问题。

答案 3 :(得分:0)

虽然像这里提到的其他人一样使用initWithCapacity:肯定没有什么坏处,但你应该从Bartosz Ciechanowski查看关于数组初始化性能的this research

  

初始容量几乎无关紧要

     

让我们分配初始容量设置为连续2的幂的新数组:

for (int i = 0; i < 16; i++) {
    NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]);
}
     

惊喜:

size:  2 // requested capacity:   1
size:  2 // requested capacity:   2
size:  4 // requested capacity:   4
size:  8 // requested capacity:   8
size: 16 // requested capacity:  16
size: 16 // requested capacity:  32
size: 16 // requested capacity:  64
size: 16 // requested capacity: 128
...
// 'size: 16' all the way down

答案 4 :(得分:0)

可以查看此问题:What is the advantage of using arrayWithCapacity

容量可以帮助理解代码作为隐式文档的一部分。 并且在初始化NSArray时,指定预期计数在性能上没有差别 - 测量的时间几乎相等且在统计不确定性范围内。

根据objc.io:https://www.objc.io/issues/7-foundation/collections/

可变阵列根据需要扩展; numItems只是建立对象的初始容量。

Apple正在讨论没有鼓励。

https://developer.apple.com/documentation/foundation/nsmutablearray/1415811-initwithcapacity?language=objc