NSData
次のように an の値をチェックするメソッドがあります。
if (data == nil) {
//Method
}
しかし、メソッド内にすべてのものがあるにもかかわらず、時間の 80% 以上が最初の行に費やされ、data
が と等しいかどうかをチェックしていることがわかりましたnil
。これを行うより効率的な方法はありますか?
スクリーンショット:
NSData
次のように an の値をチェックするメソッドがあります。
if (data == nil) {
//Method
}
しかし、メソッド内にすべてのものがあるにもかかわらず、時間の 80% 以上が最初の行に費やされ、data
が と等しいかどうかをチェックしていることがわかりましたnil
。これを行うより効率的な方法はありますか?
スクリーンショット:
との直接比較ではありませんnil
。1行に複数のステートメントがあります。
問題を分割する 1 つの方法は、ステートメントを分割することです。実装にステップインすることもできます。つまり、プロファイラーの強調表示が誤解されています。
これを分割する:
NSData * thumbnailData = self.thumbnail;
NSUInteger length = thumbnailData.length;
プロパティへのアクセスにそれほど時間はかかりません。
長さにアクセスするのにそれほど時間はかかりません (これが不変データであると仮定します)。
で遅延読み込みが行われているのではないかと思いself.thumbnail
ます。ただし、実装をドリルダウンすると、プロファイラーでより詳細な情報が得られます。
最後のポイントは、メソッドに対してローカルに解釈される可能性があることです。そのメソッドがホットスポットではなく、上記のメソッドが実際に機能しない場合、それは通常、「このメソッドを呼び出すとサムネイルが通常読み込まれる」ことを意味します。
と直接比較するよりも高速なチェック方法は絶対にありませnil
ん。少なくとも、その行をいじっても大きなパフォーマンスは得られません。このプロファイリング データは不正確です。
私の経験では、メソッド(-getThumbnail
あなたの場合)が何度も実行されていると、この種の動作(Instrumentsがメソッドの最初の行を誤って「非難」する)が発生します。-getThumbnail
が呼び出されたときに最適化してみてください。
古典的なサンプリング型のパフォーマンス プロファイラーがどのように機能するかを考える必要があります。
基本的に、プログラムの実行中に、たとえば 100 マイクロ秒ごとにタイマーがオフになり、プログラムが中断されます。次に、プロファイラーは命令ポインターを調べ、プロファイリングされるコード セグメントの開始点と終了点を基準としたその値に基づいて、整数カウンターの配列にインデックスを付け、コード アドレスに対応するカウンターをインクリメントします。
しかし、これが「完璧」であるのを妨げる (少なくとも) 3 つのことがあります。
非常に小さなプログラムを除いて、命令ごとに 1 つのカウンターを持つことは現実的ではないため、コード空間は、設定方法に応じて、たとえば 16 バイトまたはおそらく 1000 バイトの間隔に分割され、個々のカウンターがインクリメントを収集します。その範囲内のすべての命令に対して。これは、プログラムの正確な位置に関する測定の「精度」が完全ではないことを意味します。
特定のプロセッサに大きく依存しますが、通常、プロセッサは、分岐が行われたときや特定の「システム」操作が実行されたときなど、コード内の特定のポイントでのみタイマー割り込みを認識します。または、プリフェッチキャッシュが空になるまで単に待機する場合もあります。そのため、プロファイラーのタイマー割り込みが「起動」し、プロセッサがさらにいくつかの命令を実行し続ける場合があります。
特定のコード シーケンス (コンペア アンド スワップなど) は割り込みを無効にする可能性があるため、無効な領域内のすべてのアクティビティは、直後の命令で「非難」されることになります。同様に、ある種のシステム コールは、呼び出し中は割り込みを無効にする方法で行われるため、呼び出しの全コストは、直後の命令の「せい」になります。