非常に大きな数のリストがあり、それを関数に渡していくつかの操作を行いたいと考えています。もともと、inout プロパティを持つ関数を作成しました。多くの人が知っているように、swift の inout は参照渡しではなく、関数への最初のコピーを作成し、戻り値をコピーして戻します。これは高価に聞こえます。最適化してコピーの時間を短縮するために、リストをクラスでラップして参照渡しすることにしました。興味深いことに、参照渡し関数よりも inout 関数の方が高速なようです。さらに、inout 変数を操作して、コンパイラにコピー オン ライトを実行させます。inout 関数が参照渡しよりも速い理由は何ですか?
class ReferencedContainer {
var container = [Int:Bool]()
}
func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for \(title): \(timeElapsed) s.")
}
func inoutTest(list: inout [Int]?) -> [Int]? {
list![0]=1
return list
}
func refTest(list: ReferencedContainer) -> ReferencedContainer {
list.container[0] = true
return list
}
var list : [Int]? = [Int]()
for i in 0...10000 {
list?.append(i)
}
var ref = ReferencedContainer()
for i in list!
{
ref.container[i] = true
}
printTimeElapsedWhenRunningCode(title: "refTest", operation: { refTest(list: ref)})
printTimeElapsedWhenRunningCode(title: "inout", operation: { inoutTest(list: &list)})
refTest の経過時間: 0.0015590190887451172 秒。
inout の経過時間: 0.00035893917083740234 秒。