2017-10-02 5 views
0

私はPlaygroundで自分のコードをテストしましたが、ディスカッションが指摘しているようにPlaygroundはデバッグ設定です。実際のアプリケーションでこれらのコードを実行すると大きな違いはありません。前にこのデバッグ/リリースのことを知らないでください。なぜforループアプローチは地図アプローチと比較して遅いのですか?

スウィフトパフォーマンス関連の質問、私は画像のピクセルオフセットをループする必要があります、まず私はこの方法でそれを試みました。

func p1() -> [[Int]]{ 
    var offsets = [[Int]]() 
    for row in 0..<height { 
     var rowOffset = [Int]() 
     for col in 0..<width { 
      let offset = width * row + col 
      rowOffset.append(offset) 
     } 
     offsets.append(rowOffset) 
    } 
    return offsets 
} 

しかし、それは私が検索し、見つかったいくつかのコードスニペットループをオフセットこの方法によって、非常に遅いです:

func p2() -> [[Int]]{ 
    return (0..<height).map{ row in 
     (0..<width).map { col in 
      let offset = width * row + col 
      return offset 
     } 
    } 
} 

私は高さ= 128を介してループする機能P1およびP2を使用している場合ので、私はテストされ、 width = 128 image、p1はp2よりも18倍遅く、なぜp1はp2に比べて遅いのですか?私はこの仕事のための他のより速いアプローチがあるのだろうか?

答えて

1

mapの方が高速である最も明白な理由は、mapが(結果として得られる配列に含まれる要素の数を知っているので)配列の容量を先頭に割り当てるためです。コード内でこれを行うには、配列上のary.reserveCapacity(n)を呼び出します。

func p1() -> [[Int]]{ 
    var offsets = [[Int]]() 
    offsets.reserveCapacity(height) // NEW LINE 
    for row in 0..<height { 
     var rowOffset = [Int]() 
     rowOffset.reserveCapacity(width) // NEW LINE 
     for col in 0..<width { 
      let offset = width * row + col 
      rowOffset.append(offset) 
     } 
     offsets.append(rowOffset) 
    } 
    return offsets 
} 
+0

おかげで、これを使用することにより、それが改善したが、少しだけ、マップはまだ – XueYu

+0

@XueYuあなたがデバッグ中のテストや構成をリリースしています圧倒的に勝ちましたか? stdlibは最適化されてコンパイルされるので、 'map'バージョンは両方とも速くなりますが、あなたのカスタムバージョンはReleaseよりもDebugよりもずっと速くなります。 –

+0

私はちょうど遊び場で非常に簡単なテストを行い、CACurrentMediaTime()を使って使用時間を表示します。 – XueYu

関連する問題