2015TweetPocketスマホデバイスのスペックも向上し、Swiftのコンパイラのパフォーマンスも上がり続けていますが、ちょっとしたパフォーマンスが気になることはよくあります。スマホアプリではパフォーマンス次第では使い勝手が極端に悪くなります。finalやprivateを駆使したパフォーマンス改善はJava等の多言語でもおなじみで応用が効くものです。無闇にfinalやpriavteをつけている場合も多いでしょうが、パフォーマンス改善の理屈が分かると上手に使用できるようになると思います。Optimization)は開発時は不要ですが、リリース時には必ず実行しておきたいですね。他の多くの言語と同じく、Swiftでも親クラスで定義されたメソッドやプロパティをクラス内でオーバーライドすることができます。このため、プラグラムはどのメソッドやプロパティが参照されているかを実行時に決定してから、間接的にメッソドを呼び出したりプロパティにアクセスしたりしなければなりません。これは動的ディスパッチという技術で、間接的に使用されることによる実行時のオーバーヘッドをある程度犠牲にして、言語としての表現度を高めてくれます。パフォーマンスが気にかかるコードではそのようなオーバーヘッドは望ましくありません。この記事では動的な処理を取り除いてパフォーマンスを向上させる3つの手段(final、private、全モジュール最適化)を紹介します。次の例を考えてみましょう。newV:i*1000)}上記では、コンパイラは動的ディスパッチによる呼び出しを以下の順で行います。pインスタンスのupdateメソッドを呼び出すpインスタンスのupdatePointメソッドを呼び出すpインスタンスのプロパティpointにアクセスするpインスタンスのプロパティvelocityにアクセスするこのコードでは動的な呼び出しは期待していないかもしれません。PartialModelのサブクラスでは計算されたプロパティでpointやvelocityをオーバーライドするかもしれないし、別の実装でupdatePoint()やupdate()をオーバーライドするかもしれませんので、動的な呼び出しは必要なのです。Swiftでは、動的ディスパッチ呼び出しはメソッドテーブルから関数を探しだし、それから間接的な呼び出しを実行するように実装されています。このために直接的な呼び出しと比較してパフォーマンスが劣るのです。間接的な呼び出しはコンパイラによる最適化の多くにとって邪魔であり、さらにパフォーマンスが悪くなる原因となっています。パフォーマンスが厳しいコードでは、動的な処理を必要としていないときにはパフォーマンス向上のために、それらを制限する手段があります。定義がオーバーライドされる必要がないときはfinalを使うfinalという予約後はクラス、メソッド、プロパティに定義がオーバーライドされないように制限を加えるものです。これにより、コンパイラはダイナミックディスパッチによる間接的な呼び出しを安全に省力することができます。以下のpointとvelocityはロード時にオブジェクトに格納されたプロパティから直接アクセスすることができます。updatePoint()は直接関数を呼び出すことができます。update()は動的ディスパッチ経由のままで、サブクラスで機能をカスタマイズしてオーバーライドすることができます。newV)}}クラス自身に属性をつけることで、クラス全体をfinalにすることもできます。サブクラスをつくることを禁じて、クラスの関数やプロパティすべてをfinalとして扱います。...}予約後privateを適用することでファイル内で参照されている宣言からfinalを推定する宣言に予約後privateをつけることで、その宣言の可視範囲を現在のファイル内に制限します。することでコンパイラはオーバーライドしている可能性のある宣言をすべて見つけることができます。宣言がオーバーライドされていないとわかると、コンパイラは自動的にfinal予約語がついていると推定してメソッド呼び出しやプロパティアクセスを間接的に行なうのをやめます。現在のファイル内にはParticleModelをオーバーライドしているクラスはないと仮定すると、コンパイラはprivateな宣言へのすべての動的ディスパッチによる呼び出しを直接呼び出しに変更します。newV)}}この例では、pointとvelocityには直接アクセスし、updatePoint()を直接呼び出すことができます。update()はprivateではないので間接的に呼び出されます。finalと同様、private属性をクラスの宣言自身につけることができます。することでクラスとクラス内のすべてのプロパティとメソッドはprivateとして扱われます。Optimization)を使用するinternalな宣言(デフォルでは宣言に何もついていないとそうなります)は宣言されたモジュール内でのみ可視されます。コンパイラは通常はモジュールを分割して記述してあるファイルごとにコンパイルするので、別のファイル内でinternalな宣言がオーバーライドされているかどうかを判断することができません。モジュール全体最適化を有効にすると、全モジュールを一度にコンパイルします。これによりコンパイラはモジュール全体を通しての推定を行なうことができるようになり、internalな宣言の可視範囲内にオーバーライドがなければその宣言をfinalと推定します。最初のコードに戻って、ParticleModelに予約後publicをつけてみましょう。Optimization)でコンパイルすると、コンパイラはプロパティのpoint、velocityとメソッド呼び出しのupdatePoint()をfinalと推定します。対照的に、update()はpublicアクセスを持っているので、finalと推定することはできません。