パフォーマンスを高める Swift の記述

はじめに

Swift の実行速度を向上させたくドキュメントを探すと以下が見つかった。

swift/OptimizationTips.rst at master · apple/swift · GitHub

この中から気になったトピックをメモする。

Dynamic Dispatch(動的な呼び出し)を削減する

Swift は Objective-C 同様に動的な言語である。このためダイナミズムを削減したコードはそのぶん、パフォーマンスが向上する。

"final" キーワードを使用する

オーバーライドが必要ないクラス、メソッド、プロパティには final キーワードを使用する。

"private" "fileprivate" キーワード使用する

外部から参照しないものには private fileprivate を使用する。

コンテナを効果的につかう

Swift 標準ライブラリには Array と Dictionary のコンテナがある。これを高パフォーマンスに使用するように気をつける。

Array では Value types(値型) を使用する

Swift の型は大きく二つに分けることができる

  • Value types(値型)
  • Reference types(参照型)
    • class

この二つの主な違いは Value types は NSArray に含めることが できない ということ。

これはつまり Value types を Array に使う限り、それが 「NSArray に戻される可能性」がなくなり、その可能性を維持するためのオーバーヘッドが削除できることに繋がる。

さらに Reference types は参照カウントが必要だが、 Value types は参照型が含まれている場合のみ、参照カウントが必要になる。
このため、Reference types の無い Value types を使用することにより、Array 内での retain/release のトラフィックを避けることができる。

ただし、Value types には注意が必要。
上記の参照カウントをもたないことのメリットの裏には Value types のコピーのコストがある。
つまり Value types が大きな場合、コピーのコストが大きくなり、それがこれまであげたメリットを上回る可能性に注意する必要がある。

チェックしない演算子

Swift では演算実行のタイミングでオーバーフローをチェックする。
しかし、フローの問題が発生しないとわかっている時は、このチェックを省略すると、チェックにかかる時間が無くなる。

a : [Int]

for i in 0 ... 100 {
  a[i] = i &+ (i+1)  // この演算はオーバーフローしないので & をつけてチェックを省略する
}

そのほか

  • ここに書いていないトピックも原文に目を通しておくと良い。
  • とくに Generics に関してはきっと役立ちそう
  • ここに記載した事柄をとりこんでみた結果、下のライブラリは実行速度が向上した

おわり