[Swift] コレクション(Array)のループ速度比較

下記の3パターンで速度比較を行ってみた
・パターンA
 Cスタイルなループカウンタを使ったforループ
 objective-cでは遅かったが。。。

・パターンB
 enumerateを使ったfor-inループ
 要素のループと同時にindexを求めることが可能
 きっと遅いな。これは。

・パターンC
 for-inループ(objective-cのFast Enumeration)
 直接indexは求めることが出来ないけどきっと速いはず

実行時間を取るためにこんな関数を用意して


func currentTime() -> Double {
    return ((CFAbsoluteTimeGetCurrent() as Double) * 1000.0)
}

下記のコードで検証しました


// 10万要素の配列を作成
// こういったデータもSwiftでは簡単に作成できます。
let testValues = Array(count:100000,repeatedValue:2)

var total = 0,startTime=0.0,interval=0.0

// パターンA
// Cスタイルなforループ
total = 0
startTime = currentTime()
for var i = 0; i < testValues.count; i++ {
    total += testValues[i]
}
interval = currentTime() - startTime
NSLog("patttern-A takes \(interval)ms total:\(total)")

// パターンB
// enumerateを使った for-in ループ
// scalaの zipWithIndex みたいなやつ
total = 0
startTime = currentTime()
for (index,v) in enumerate(testValues){
    total += v
}
interval = currentTime() - startTime
NSLog("patttern-B takes \(interval)ms total:\(total)")


// パターンC
// indexを求めない for-in ループ(foreachだね)
total = 0
startTime = currentTime()
for v in testValues {
    total += v
}
interval = currentTime() - startTime
NSLog("patttern-C takes \(interval)ms total:\(total)")

結果は速い順で a > c > b の結果となった
実際の計測結果はまだいろいろ問題がありそうなので伏せておきますが、
一番速かったAを100%とした場合Bが159%、Cが123%の実行時間でした。
※これは処理順を変えても同様だった

予想通りenumerate を使ったループが一番遅かった。
予想と違ったのはパターンCよりパターンAが速かった事。objective-cでは要素をインデックスによって求めると遅かったけどSwiftでは気にしなくていいみたい。

AとBでは約1.6倍の処理速度差があるので、大量データの処理時には気をつけたほうが良いかもね。

(2014-09-19追記)
XCode6.0.1で再検証すると、パターンAとCではほとんど差が無くなりました。
それでも2〜3%ほどパターンAの方が速いですが、コードの見やすさを考えると積極的にパターンCを使って良いのではないかと。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です