Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如果我创建一个容量为3而不是50的NSMutableArray,这有多重要?_Iphone_Cocoa Touch_Arrays_Uikit - Fatal编程技术网

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

Iphone 如果我创建一个容量为3而不是50的NSMutableArray,这有多重要?,iphone,cocoa-touch,arrays,uikit,Iphone,Cocoa Touch,Arrays,Uikit,我想知道这是否会对性能或内存消耗造成很大影响。我需要一个NSMutableArray,一开始我只能猜测将添加多少个对象。大概3到5点。所以我这样创建它: NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:3]; 例如,当创建容量为3而不是50时,这里到底发生了什么?在知道至少有20个元素的情况下,以1的容量创建它会是一个坏主意吗?或者这还不足以让人头疼吗?我的应用程序中有10个这样的阵列,它们都必须在启动时加载 这没什

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

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

例如,当创建容量为3而不是50时,这里到底发生了什么?在知道至少有20个元素的情况下,以1的容量创建它会是一个坏主意吗?或者这还不足以让人头疼吗?我的应用程序中有10个这样的阵列,它们都必须在启动时加载

这没什么大不了的,除非你说的是极端重复或大量数组。除非它成为真正的瓶颈,否则不值得尝试优化

编辑:我想引用Donald Knuth的话:

过早优化是万恶之源。


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

从实际的角度来看,阵列将根据需要重新分配,并且与您所讨论的数字相比,我怀疑会有任何区别。如果我知道我会把成千上万的东西放进去的话,我可能会做一个有容量的阵列。3比50基本上毫无意义

从我的角度来看,“withCapacity”的最佳用途就是提供一个明显的钩子来挂起您的假设,这样您就可以(例如)在代码文档中包含您以后可能想要断言的内容。但这绝对不是必需的


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

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

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

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


我的建议是,如果您知道数组的大小通常不会超过N项,请调用
initWithCapacity:N
。偶尔
NSMutableArray
大于N的性能损失是可以接受的,并且您不必为那些没有超过该限制的阵列支付损失。

虽然使用
initWithCapacity:
肯定不会有任何伤害,但与这里提到的其他阵列一样,您应该从Bartosz Ciechanowski了解阵列初始化性能:

初始容量几乎不重要

让我们分配新阵列,初始容量设置为两个连续幂:

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

请检查以下问题:


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

根据objc.io:


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

苹果博士的讨论没有鼓励


这是什么意思?我的英语不是很好;-)请解释一下。谢谢这意味着:除非你a)真的需要它运行得更快,b)找出慢的部分,否则不要优化代码的性能。否则,你只会使你的代码变得更复杂,增加复杂性,花费时间而没有任何好处。非常详细!其他答案也很好。发现选择一个被接受的人从来没有这么难。所有人都投了赞成票。谢谢大家!恕我直言,我认为这个答案是错误的。虽然容量在某些情况下用于暗示,但创建容量为千兆字节的可变阵列不会立即分配千兆字节的内存。如果你不相信我,你自己试试看。NSMutableArray*bigArray=[[NSMutableArray alloc]initWithCapacity:1024*1024*1024];如果(!bigArray){NSLog(@“Array was not created!”);}或者{NSLog(@“yes,it is created.”);}如果您实际填充此数组,您将看到内存使用量增加。以前没有。initWithCapacity的文档声明它返回“一个初始化了足够内存以容纳numItems对象的数组”。peterb观察到的结果和文档声称的结果之间似乎存在一些差异。这对于测试和测量来说是微不足道的。试一试,让我们知道你发现了什么。我坚持我的主张。我并不是有意暗示我不同意你的观点,或者认为你的实验不知何故是无效的。在软件中,文档与实现之间的差异并不少见,它们在哪里做,代码做什么才是真正重要的。
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