何百万もの計算を実行する必要がある非常に大きな配列がいくつかあります。Objective-C では、配列は NSData として格納され、それらを C 配列に抽象化して、Accelerate 関数 (sum、add など) を使用します。ただし、(どこでもポインターを使用することに関する明らかな問題を考えると) Swift 配列に組み込まれている境界チェックをもっと活用したいと思います。したがって、ネストされた withUnsafeBufferPointer を使用して、2 つの配列を操作できます。
func mult(_ x: ArraySlice<Double>, _ y: ArraySlice<Double>) -> [Double] {
assert(x.count == y.count)
var results = [Double](repeating:0, count: x.count)
x.withUnsafeBufferPointer({xBuffer in
y.withUnsafeBufferPointer({yBuffer in
vDSP_vmulD([Double](xBuffer), 1, [Double](yBuffer), 1, &results, 1, vDSP_Length(xBuffer.count))
})
})
return results
}
var testArray = [Double]([0,1,2,3,4,5,6,7,8,9,10])
var testArray2 = [Double]([2,2,2,2,2,2,2,2,2,2,2])
let results = mult(testArray[5...10], testArray2[5...10])
print("\(results)")
まず、コンパイラが [Double] 自体をキャストする方法を既に知っている場合、意図した型としてポインターを再キャストすることは奇妙に思えます (ブロック内で渡されるポインターの型は ですUnsafeBufferPointer<Double>が、vDSP 関数は期待されますUnsafePointer<Double>(ここでも、配列変数自体を渡した場合の苦情))。withUnsafeBufferPointer第二に、使用法は理解していますが、見栄えをネストする必要があります。最後にArraySlice<Double>、入力パラメーターの型として使用すると、関数を Double 配列とその配列のスライスの両方に一般化できません。
これを行うより良い方法はありますか?