创建具有固定计数的Swift Array <float>的最快方法

时间:2019-01-22 23:12:49

标签: arrays swift optimization unsafemutablepointer

我注意到了这一点

let a = [Float](repeating: 0, count: len)

花费的时间远远超过

let p = UnsafeMutablePointer<Float>.allocate(capacity: len)

但是,不安全的指针使用起来不太方便,因此可能需要创建一个Array<Float>才能传递给其他代码。

let a = Array(UnsafeBufferPointer(start: p, count: len))

但是这样做绝对会杀死它,并且创建带有填充零的Array更快。

有人知道如何更快地创建Array并同时方便实际使用Array<Float>吗?在我的项目上下文中,我可能可以在内部处理不安全的指针,并且仅在模块外部需要时才用Array包装它。

快速测试本文中的所有答案:

let len = 10_000_000

benchmark(title: "array.create", num_trials: 10) {
    let a = [Float](repeating: 0, count: len)
}

benchmark(title: "array.create faster", num_trials: 10) {
    let p = UnsafeMutableBufferPointer<Float>.allocate(capacity: len)
}

benchmark(title: "Array.reserveCapacity ?", num_trials: 10) {
    var a = [Float]()
    a.reserveCapacity(len)
}

benchmark(title: "ContiguousArray ?", num_trials: 10) {
    let a = ContiguousArray<Float>(repeating: 0, count: len)
}

benchmark(title: "ContiguousArray.reserveCapacity", num_trials: 10) {
    var a = ContiguousArray<Float>()
    a.reserveCapacity(len)
}
benchmark(title: "UnsafeMutableBufferPointer BaseMath", num_trials: 10) {
    let p = UnsafeMutableBufferPointer<Float>(len) // Jeremy's BaseMath
    print(p.count)
}

结果:(1000万浮动)

array.create:9.256毫秒

array.create更快:0.004毫秒

Array.reserveCapacity?:0.264毫秒

ContiguousArray吗?:10.154毫秒

ContiguousArray.reserveCapacity:3.251毫秒

UnsafeMutableBufferPointer BaseMath:0.049毫秒

我正在通过释放模式在iPhone模拟器上专门运行一个应用程序。我知道我可能应该在命令行/独立模式下执行此操作,但是由于我计划将其编写为应用程序的一部分,因此可能没问题。

对于我尝试做的事情,UnsafeMutableBufferPointer看起来很棒,但是您必须使用BaseMath及其所有一致性。如果您追求的是一般性或其他背景。请务必阅读所有内容,并确定哪一种适合您。

2 个答案:

答案 0 :(得分:1)

如果需要性能,并且知道所需的大小,可以使用reserveCapacity(_:),这将为数组的内容预分配所需的内存。根据Apple文档:

  

如果要向数组中添加已知数量的元素,请使用此方法避免多次重新分配。此方法可确保数组具有唯一的,可变的,连续的存储,并至少为请求的元素数量分配了空间。

     

在具有桥接存储的阵列上调用reserveCapacity(_ :)方法会触发向连续存储的复制,即使现有存储有空间可以存储minimumCapacity元素。

     

出于性能原因,新分配的存储大小可能大于请求的容量。使用阵列的Capacity属性确定新存储的大小。

答案 1 :(得分:0)

这是最接近我想要的东西。有一个名为BaseMath的库(由Jeremy Howard开始),还有一个新的类,名为AlignedStorage和UnsafeMutableBufferPointer。它具有很多数学功能,而且非常快,因此可以减少使用数学算法时指针的管理。

但这还有待测试,这个项目是非常新的。我将保留此问题,以了解是否有人可以提出更好的建议。

注意:这是我正在做的事情中最快的。如果您确实需要一个好的结构值类型Array(和变体),请参阅其他答案。