当我使用NSMutableArray
或NSMutableDictionary
时,如果我知道要放入的元素数量或元素的最大数量,我通常会使用arrayWithCapacity
或{{dictionaryWithCapacity
创建它们1}},但我想知道为数组/字典指定(初始)容量真的有用吗?
我不知道它是如何在内部实现的,但我相信当集合中的元素数量达到容量甚至接近容量时,集合可能会扩展其容量,所以如果我创建了一个容量为32的可变数组,只要我将第32个对象放入其中,它就会将自身扩展到另一个容量?或者即使我把第30个对象放入其中,它的容量也会扩大,因为它认为会有更多的对象?
因此,如果这些方法确实有用,我应该使用类似的东西:
*withCapacity:maxNumberOfElements * 1.5
而不是
*withCapacity:maxNumberOfElements
所以它对我的对象有足够的容量,当我放入所有对象时不会扩展?
答案 0 :(得分:0)
从性能角度来看,它很有用。当容量经常扩展时,在内存中分配一个新数组(通常是当前容量的2倍),旧数组被复制到新数组。随着元素数量的增加,这可能开始变得昂贵,所以如果你有大容量(大致)预先知道的数组,建议使用initWithCapacity。另一方面,如果你分配的东西比你需要的大得多,你就是在浪费空间,所以标准的“谨慎使用”警告适用。
答案 1 :(得分:0)
实际上,除非你创建了大量的数组/字典(与呈现UI页面的频率相比),否则使用...WithCapacity
的性能不会有明显改善。即使这样,除非你有至少几百个条目的数组/字典,否则没有必要担心它。
就猜测的大小而言,最终大小可能只有一点(5-10%)是理想的,但这在一定程度上取决于你是否容易受到存储限制。
但是,如果您确切知道有多少条目,请指定确切的金额(如果您指定了任何内容)。
答案 2 :(得分:0)
当您计划使用大量元素填充集合时,或者当您知道要加载的元素的确切数量时,这非常有用。调整集合大小需要占用CPU周期,因此不必要地调整大小最终会缩短设备在电池上运行的时间。
考虑这个例子:让我们假设您要将3000个元素加载到数组中。如果为具有16个项目的空间分配默认数组,则在达到保存3000个元素所需的大小之前,该数组需要调整大小八次。每次调整数组大小时,都需要复制在初始位置复制的元素,从而导致3000多个额外的复制操作。当您知道元素的确切数量时,可以防止复制发生。
此外,您的阵列不会浪费您不会添加的元素的内存:如果您逐个添加3000个元素,则阵列可能会在内部增长到4000,以期有更多元素;最后1000个元素将被浪费。
总而言之,如果您确切知道确切的目标大小,则应该使用容量初始化集合。当您从文件或网络连接反序列化数据时,通常会出现这种情况。在您不知道大小的情况下,最好不要猜测,并让默认初始化运行。