使用arrayWithCapacity有什么好处

时间:2014-07-25 14:19:34

标签: ios objective-c

arrayWithCapacity NSArray.h 中定义的方法,并在 NSArray.m

中实施

当我查看GNUStep提供的代码时,我可以得到arrayWithCapacity是一种调用initWithCapacity的常规方法:

+ (id) arrayWithCapacity: (NSUInteger)numItems
{
    return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
    initWithCapacity: numItems]);
}

initWithCapacity是一种只进行自我初始化的简单方法。

- (id) initWithCapacity: (NSUInteger)numItems
{
  self = [self init];
  return self;
}

没有关于执行项目数量的内存分配 使用arrayWithCapacity方法有什么好处?简单地使用[[NSArray alloc] init]

是否更好?

3 个答案:

答案 0 :(得分:8)

期望提供显式大小可以改善内存分配,因为在添加项目时无需调整数组的大小。在实践中,它只是一个提示,并且有一些证据证明它实际上并未使用(请参阅基础集合类中的objc.io article)。

答案 1 :(得分:2)

这些方法实际上是NSMutableArray的一部分,而不是NSArray

它为实现提供了一个关于你想要存储多少项的提示,因此它可以预先分配足够的内存而不是根据需要增加内存,这可能很昂贵,因为它可能涉及分配,从旧的复制内存到新的,释放旧记忆。如果你添加了很多项目,这种增长可能会发生很多,所以如果NSMutableArray可以一次性分配所需的内存量,效率会更高。

请记住,这只是一个提示,实现可能会忽略它。实际上,CFArray/CFMutableArray 在创建可变数组时忽略容量

static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const CFArrayCallBacks *callBacks) {
    struct __CFArray *memory;
    UInt32 size;
    ...
    switch (__CFBitfieldGetValue(flags, 1, 0)) {
        case __kCFArrayImmutable:
            size += capacity * sizeof(struct __CFArrayBucket);
            break;
        case __kCFArrayDeque:
        case __kCFArrayStorage:
            break;
    }
    ...
    return (CFArrayRef)memory;
}

CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) {
    ...
    return (CFMutableArrayRef)__CFArrayInit(allocator, __kCFArrayDeque, capacity, callBacks);
}

根据@azsromej链接的this articleNSMutableArray似乎也忽略了提示。

答案 2 :(得分:1)

这适用于NSMutableArray,因为NSArray没有方法arrayWithCapacity,这也适用于initWithCapacity

从运行时POV中使用arrayWithCapacity可以忽略不计。它可以被认为是一种过早的优化。

它确实有缺点,或者需要一些时间和/或代码来提出一个很少提供有意义的时间优势并增加心理负担的值。

它也被认为是暗示,可能会或者不会被使用,这是Apple可以在任何时候改变的实现细节。

注意:我使用和不使用容量提示进行了时序测试,节省的时间(如果有的话)是一个非常小的百分比。

有关NSArray的详细信息,请参阅ridiculousfish

@bbum评论:"文档只是状态建立初始容量,而不是数组已分配内存来容纳所有容量。 Array的后备存储不是线性分配的内存块,细节随阵列的大小而变化。"