26

在决定容量时,是否有人对如何最好地初始化 NSMutableArray 有建议?文档中提到“......即使您在创建数组时指定了大小,指定的大小也被视为“提示”;数组的实际大小仍然为 0。” 所以...

1)如果我用比我通常使用的更大的容量初始化,我不必担心浪费内存吗?

2)如果我初始化的容量通常低于我使用的容量,我是否必须担心更重的处理时间会分配更多内存来容纳额外的元素?

这种初始化容量对这种数据类型的性能/内存使用有多大影响?

4

2 回答 2

41

Matt Gallagher写了一篇关于 Cocoa 集合类的内容丰富的文章,以及一些基准测试(有和没有initWithCapacity:,以及跨类比较)

http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html

他对长度为 1,000,000的 NSMutableArray 的测试(可用资源)在无容量的情况下耗时0.582256 秒,在有容量的情况下仅耗时 0.572139 秒。

测试 | 时间
[NSMutableArray 数组] | 0.582256 秒
[NSMutableArray arrayWithCapacity:1000000] | 0.572139 秒
迭代内容 | 0.004713 秒

我会说在 99% 的用例[NSMutableArray array]中都很好。但是,如果您确实知道生成的数组的实际大小,那么使用它们也没有什么坏处[NSMutableArray arrayWithCapacity:]


然后是Peter AmmonApple 的 AppKit/Foundation 团队的开发人员)的这篇文章,其中包含几个有见地的基准

http://ridiculousfish.com/blog/archives/2005/12/23/array/


编辑(2012 年 3 月 12 日):

从http://darkdust.net/writings/objective-c/nsarray-enumeration-performance 获得更多关于数组初始化性能的见解

[…] 我 [=>DarkDust] 还想知道性能是否会因阵列的创建方式而有所不同。我测试了两种不同的方法:

  • 创建一个引用对象实例的 C 数组并使用initWithObjects:count:.
  • 创建 aNSMutableArray并随后使用 . 添加对象addObject:

[…] 分配时有一个区别:initWithObjects:count: 方法更快。对于非常多的对象,这种差异会变得显着


编辑(2014 年 3 月 6 日):

从http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/进一步了解数组初始化性能:

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

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

惊喜惊喜:

size: 2 // 请求容量:1
size: 2 // 请求容量:2
size: 4 // 请求容量:4
size: 8 // 请求容量:8
size: 16 // 请求容量:16
size: 16 // 请求容量:32
size: 16 // 请求容量:64
size: 16 // 请求容量:128
...
// 'size: 16' 一直向下

于 2010-10-16T12:05:22.633 回答
15

我猜,是否通过提供太大的容量而浪费任何空间实际上是Apple故意不公开的实现细节。NSMutableArray 是一个类集群,这意味着您实际上并没有获得 NSMutableArray 的实例,而是其他一些遵循相同接口的专用类。而且 Apple 不会告诉您在哪种情况下会返回哪个类以及它的行为方式。所以在这里很难给出真正的建议。

如果您真的知道平均需要X容量,请使用它。否则,除非您有性能问题,否则我根本不会关心容量,只需使用[NSMutableArray array]...

于 2010-10-16T07:56:25.950 回答