質問
次のうち最もパフォーマンスが良いのはどれですか?
メソッド 2 を JavaScript で実装するとパフォーマンスが大幅に向上することを確認しましたが、C# ではパフォーマンスの向上を測定できず、メソッド 1 のように記述した場合でもコンパイラがすでにメソッド 2 を実行しているのではないかと疑問に思っていました。
方法 2 の背後にある理論は、コードは反復ごとに DataTable.Rows.Count にアクセスする必要はなく、単純に int c にアクセスできるということです。
方法 1
for (int i = 0; i < DataTable.Rows.Count; i++) {
// Do Something
}
方法 2
for (int i = 0, c = DataTable.Rows.Count; i < c; i++) {
// Do Something
}
解決
いや、表現する方法がないのでそれはできません 時間が経っても一定 価値のために。
コンパイラーがそれを実行できるようにするには、値を返すコードから、その値が定数であり、ループの継続中は変更されないという保証が必要になります。
ただし、この場合、ループの一部としてデータ テーブルに新しい行を自由に追加できるため、これまでの方法でそれを保証するかどうかはユーザー次第です。
つまり、終了インデックスが変数以外の場合、コンパイラは最適化を実行しません。
変数の場合、コンパイラはループ コードを確認するだけで、この特定の変数が変更されていないことを確認できます。ループを開始する前に値をレジスタにロードする可能性がありますが、これによってパフォーマンスが向上することはありません。ループ本体が空でない限り、おそらく無視できるでしょう。
結論:ループ終了インデックスがループ期間中一定であることがわかっている場合、または受け入れるつもりがある場合は、それを変数に入れます。
編集: 投稿を読み直してみると、確かに、JITter がコードを最適化しているため、2 つのケースでもパフォーマンスの向上は無視できるかもしれません。JITter は、行数を含むデータ テーブル内の変数への直接アクセスへの終了インデックスの読み取りを最適化する可能性があり、メモリ読み取りはとにかくそれほど高価ではありません。一方、そのプロパティの読み取りが非常にコストのかかる操作である場合は、より顕著な違いがわかるでしょう。