3

操作でオーバーフロー例外を強制的にスローする方法について読んでいますが、「自分で試してください」セクションで、本とは別の場所にありました。checkedキーワードの根底にあるメカニズムがよくわからないので、どちらかのスポットに関連するパフォーマンスの問題があるかどうか興味があります.

この本の例では階乗を行っていましたが、符号なし long であってもすぐにオーバーフローがスローされます。これは私が思いついたコードです:

static long Factorial (long number) {
    long result = 1;

    for (int i = 2; i <= number; i++) {
        checked {
            result *= i;
        }
    }

    return result;
}

しかし、本の裏にある回答ページを見ると、とcheckedを含む関数の本体全体が で囲まれていました。明らかに、それらの場所で必要になることは決してないので、どちらかといえば、ループを でラップするだけです。returnlong result = 1;forcheck

ループ内に存在すると、基になる CLR コードが繰り返し生成されますか? (for ループに入る前に変数を宣言する理由のように。) または、ループ内に変数を持っているオーバーヘッドはありませんか?

4

1 に答える 1

4

コンパイル結果に関しては、ほとんど違いはありません。

主な違いは、ブロック内のすべての算術演算checkedが異なる IL 命令を使用することです。これ以上の指示はありません。異なる指示だけです。の代わりにmulmul.ovf- の代わりに、などaddを取得します。add.ovf

ただし、実際のバージョンの動作はわずかに異なります。checkedブロックをより厳密なスコープに配置しているため、変数のインクリメント ( )i++はまだチェックされていません。オリジナルはずっとチェックされていたはずi++です。つまり、乗算演算だけでなく、スローされる可能性があります。これは、バージョンが高速であることを意味しますが、スコープの変更によるものではなく、オーバーフロー チェックを回避し、結果の動作を変更したためです。

ループ内に存在すると、基になる CLR コードが繰り返し生成されますか?

いいえ、それは、そのスコープ内の IL 命令が、標準のものではなく、オーバーフロー チェックを使用してさまざまな IL 操作コードを取得することを意味するだけです。

または、ループ内にオーバーヘッドはありませんか?

オーバーヘッドはありません (命令自体のチェックの余分なオーバーヘッドを除いて)。

于 2014-04-09T16:54:08.127 に答える