Home > C# > C# Performance#1 – checked/unchecked operations

C# Performance#1 – checked/unchecked operations

It’s time to write something in my cripple English :)

Reading many articles about .NET and C# I found some topics that I was really interested to make some experiments.

Sometimes digging in web or C# books I found that unchecked operations are faster than checked.

The checked operation is any arithmetic operation on primitives ( such as integers, floats) that are overflow checked or unchecked. This means that when You reach the capacity of a byte variable which is 255 and You add 10 to the variable, the runtime will inform You that You overflowed the value throwing an OverflowException when checked is enabled or will omit this situation continuing program execution (sometimes this can behave strange) and inserting 10 to the variable. The first behavior sometimes is desired for example making a bank calculations or generating hash codes (Ouch, I wrote bank operations, for this better is Double type).

By default the C# compiler compiles the code with the unchecked flag. Every arithmetic operation will not be checked for the overflow. This results in faster code execution. The programmer can also constrain that the code will be checked using the /checked+ flag in the compiler, making that the whole code will be checked. The behavior if the code is compiled to checked or not depends on language (or mainly by the compiler). Programmer can only check a couple lines of code making that the rest will be unchecked, this can be done with the checked { } or unchecked { } blocks. More about the operators can be found in web or books.

When You open the compiled checked code using a IL Disassembler You can see, that arithmetic operations such as adding, multiplying or subtracting were represented by add.ovf, mul.ovf or sub.ovf IL instructions. When You open the unchecked code by the IL Disassembler You will see the no overflow checking instructions such as add, mul or sub. The one exception is Decimal, which is a special type and it’s always checked. A piece of checked/unchecked IL instructions for Int32 are presented below (see the lines 14, 18). Interesting is line 1c.

Checked Int32 Unchecked Int32

IL_0010:  br.s       IL_0022
IL_0012:  ldloc.1
IL_0013:  ldc.i4.1
IL_0014:  add.ovf
IL_0015:  stloc.1
IL_0016:  ldloc.1
IL_0017:  ldc.i4.2
IL_0018:  mul.ovf
IL_0019:  stloc.1
IL_001a:  ldloc.1
IL_001b:  ldc.i4.2
IL_001c:  div
IL_001d:  stloc.1

IL_0010:  br.s       IL_0022
IL_0012:  ldloc.1
IL_0013:  ldc.i4.1
IL_0014:  add
IL_0015:  stloc.1
IL_0016:  ldloc.1
IL_0017:  ldc.i4.2
IL_0018:  mul
IL_0019:  stloc.1
IL_001a:  ldloc.1
IL_001b:  ldc.i4.2
IL_001c:  div
IL_001d:  stloc.1

 

I was really interested in, what is the performance count of both the checked and unchecked operations.

I wrote some simle procedures for the Int32 and Double primitives and checked and unchecked operations. The procedure is doing some iterations (about 20’000’000) making a simple arithmetic operations. I’m counting the calculation time making about 20 tests. The average result time is presented below:

Checked Int64

Unchecked Int64

993,15 ms

751,15 ms

Checked Double

Unchecked Double

1000,7 ms

798 ms

Checked Int32

Unchecked Int32

231,65 ms

227,55 ms

Checked Decimal

Unchecked Decimal

6120,1 ms

6108,3 ms

As You can see, in fact the execution time of both, checked and unchecked operations are different, making the unchecked execution faster. As I wrote earlier the Decimal is always ‘checked’ and the execution time is almost the same (compare with the double, where the time differs).

The main difference for Decimal is that the CLR does not have IL instructions such add or mul only uses overloaded operators. This can be observed in IL Disassembly (multiply operation)

Decimal Checked

IL_0025:  call       valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Multiply(valuetype [mscorlib]System.Decimal,    valuetype [mscorlib]System.Decimal)

 

The time of Int32 is mostly the same for both checked and not, but when making more iterations the difference slowly grows.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: