我正在进行一个涉及非常大的动态数组的Swift项目。 我遇到的问题是,每个操作所需的时间比前一个更长。 我相信这个问题是由于向数组附加元素引起的,因为我在一个简单的测试中只向一个大型数组附加元素也遇到了同样的问题。
我的测试代码:
这个程序尝试在10000到1000000之间测试100个不同的数组大小,计时向数组末尾添加一个项目所需的时间。据我了解,Swift数组是动态数组,将以几何方式重新分配内存(每次需要重新分配时都会分配更多的内存),苹果的文档说平均而言将单个元素附加到数组是O(1)操作,即调用append(_ :)方法(source)。因此,我认为内存分配并不是引起问题的原因。
然而,数组长度与附加元素所需时间之间存在线性关系。我绘制了一堆数组长度的时间图表,除了一些离群值外,它很清楚地是O(n)。我还使用保留容量运行了相同的测试(在代码块中已注释),以确认内存分配不是问题,结果几乎相同: 如何高效地将元素添加到大型数组的末尾(最好不使用
我的测试代码:
import Foundation
func measureExecution(elements: Int, appendedValue: Int) -> Void {
var array = Array(0...elements)
//array.reserveCapacity(elements)
let start = DispatchTime.now()
array.append(appendedValue)
let end = DispatchTime.now()
print(Double(end.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000_000)
}
for i in 0...100 {
measureExecution(elements: i*10000, appendedValue: 1)
}
这个程序尝试在10000到1000000之间测试100个不同的数组大小,计时向数组末尾添加一个项目所需的时间。据我了解,Swift数组是动态数组,将以几何方式重新分配内存(每次需要重新分配时都会分配更多的内存),苹果的文档说平均而言将单个元素附加到数组是O(1)操作,即调用append(_ :)方法(source)。因此,我认为内存分配并不是引起问题的原因。
然而,数组长度与附加元素所需时间之间存在线性关系。我绘制了一堆数组长度的时间图表,除了一些离群值外,它很清楚地是O(n)。我还使用保留容量运行了相同的测试(在代码块中已注释),以确认内存分配不是问题,结果几乎相同: 如何高效地将元素添加到大型数组的末尾(最好不使用
reserveCapacity
)?
Deque
,它可能适合你的情况。 - Alladinianfor i in 0...100
循环的一次迭代,因此它将比上一个数组长10,000个索引。 - 42nd