質問

There are some good articles on the web / stackoverflow about the usage of the 'checked' keyword vs. the compiler option 'Check for arithmetic overflow/underflow', like those:

http://www.codethinked.com/c-trivia-what-no-overflow

Why doesn't C# use arithmetic overflow checking by default?

Best way to handle Integer overflow in C#?

Still I don't know which one I should use. Per default I would prefer to go with the compiler option to be always safe, to not clutter my code with the unchecked keyword, not to forget it in some places and finally it is not very commonly used, so probably unknown to many developers.

But then how bad is the actual performance hit I take? I guess MS set the default not to do the overflow checking for a good reason. Does the compiler option only concern my code or also every consumed libraries and the framework itself?

役に立ちましたか?

解決

I had the same question. I prefer piece of code to be checked by default in my company's code, because overflow side effects can cost a lot and be hard to diagnose. Discovering the real reason of those side effects can be every valuable.

The question is, what do we lose in terms of performance?

Here is a very simple bench :

static void Main(string[] args)
{
    long c = 0;
    var sw = new Stopwatch();
    sw.Start();
    unchecked
    {
        for (long i = 0; i < 500000000; i++) c += 1;
    }
    sw.Stop();
    Console.WriteLine("Unchecked: " + sw.ElapsedMilliseconds);

    c = 0;
    sw.Restart();
    checked
    {
        for (long i = 0; i < 500000000; i++) c += 1;
    }
    sw.Stop();
    Console.WriteLine("Checked: " + sw.ElapsedMilliseconds);
}

In the generated IL, I see that the checked and unchecked keyword determines whether the add.ovf or add instruction will be used. (both for Debug and Release configs)

IL_001c:  ldloc.2
IL_001d:  ldc.i4.1
IL_001e:  conv.i8
IL_001f:  add


IL_0066:  ldloc.2
IL_0067:  ldc.i4.1
IL_0068:  conv.i8
IL_0069:  add.ovf

Results (x64 host)

Debug

  • Unchecked: 2371
  • Checked: 2437

Release

  • Unchecked: 2088
  • Checked: 2266

Other results by replacing long(s) by an int(s) (x64 host)

Debug

  • Unchecked: 1665
  • Checked: 1568

Release

  • Unchecked: 189
  • Checked: 566

The performance hit is there, it looks like it is more important to choose the right variable type that to go checked or unchecked. Anyway it doesn't change my opinion. I'll turn on the "Check for arithmetic overflow/underflow" in all our projects! (Advanced Build Settings).

When in need of performance, I'll simply use an unchecked block.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top