5

コンテナー内のオブジェクトがタイトなループで頻繁に使用される場合、ローカル変数にオブジェクトを割り当てることでパフォーマンス上の利点があるかどうか、誰か教えてください。

大きな for ループがあり、ループ内でコンテナーからのオブジェクトが頻繁にアクセスされます。すなわち

for i := 0 to 100000 do
begin
  my_list[i].something := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
  my_list[i].something_else := something;
end;

を割り当てることでパフォーマンスが向上しますか?

local_ref := my_list[i];

各反復の開始時?汎用コンテナー (TList<<>MyObject<>>) を使用しています。

4

2 に答える 2

9

あなたが提案する変更を行うと、確かにコードが高速になります。ローカル変数へのアクセスは、 のプロパティ ゲッターへのアクセスよりも常に高速になりますTList<T>。まず、これらのゲッターはインデックスの有効性チェックを実行します。しかし、可能な限り単純な getter を持つクラスであっても、キャッシュされたローカルに勝るものはありません。

さて、これがあなたの場合に重要かどうかは、ここからは言えません。ループ内でリモートで自明でないことを行うと、アイテムゲッターの実行時間は無関係になります。ループが多数の反復で実行される可能性があるという事実は、重要な要素ではありません。何よりも重要なのは、各反復にどれだけの時間を費やすかです。アイテムの getter を呼び出すのに 1 時間単位、各アイテムで何をするにも 1000 時間単位のコストがかかる場合、getter のパフォーマンスは問題になりません。

最終的に、質問に答える決定的な方法は、代替案の時間を計ることです。測定に基づいてのみ最適化します。

item をローカル変数にコピーするのにはもっと良い理由があります: 表現を明確にするためです。あなたの現在のコードは、DRY の原則に著しく違反しています。

最後に、このコードは for in ループを使用した場合に最も読みやすくなります。

for Item in List do
  ....

現在、 for in ループは従来のループよりも遅くなる可能性がありますが、明快さと保守性に対してそれを重視する必要があります。通常、最適化により、コードの保守が難しくなり、障害が発生しやすくなります。結論: ボトルネックのみを最適化します。

于 2012-11-29T19:07:55.417 に答える
4

それはすべて、my_list[i]取得方法によって異なります。一連の関数呼び出しが発生する場合は、違いが生じる可能性があります (副作用は言うまでもありません)。

いつものように、パフォーマンスのリファクタリングを行う前に測定する必要があります。時期尚早の最適化.....

with記録として、これは元の Pascal 設計におけるの「良い」使用法の 1 つでした。

with my_list[i] do
begin
  something := something_else;
  [...]
end;
于 2012-11-29T19:00:49.797 に答える