Friday, April 14, 2006
Saw a strange method call tonight while answering a post...

System.Threading.Interlocked.Increment(i)

It was in a simple loop, and it turns out it was generated by a code converter (C# to VB.NET) so the poster didn't know what it was for (curiosity is far too lacking in this world, but that's a rant for another day).  Fortunately, like every other of the 7-gazillion methods in the .NET framework, if you know it's name you can look it up very easily. Ah, it is a thread-safe incrementer for use on shared variables. It ensures that the value is updated and read in an atomic transaction, in other words, other threads won't increment it as well before it is read. There is no need to use it on a local variable, but it is a potentially handy tool found in the Interlocked class.

Now, about the only time I can think you would use this would be if you had a method that provided a unique integer ID throughout an application.  I personally let SQL Server handle its own ids.  But if you don't want to use IDENTITY in SQL or aren't using a database engine to store your data, this is a handy thing to have.  It also existed in  version 1.0 of the framework, so its not something new, but its not something you'd use everyday, which raises two related questions:

1) What facacta code converter turns a simple for loop into something so arcane?
or
2) is this call used under the covers of every single loop?

Ah, found the suspected converter on the first try. Thank you Google.

It turns this simple loop

for(int i=0;i<10;i++)
{
    Debug.WriteLine(i);
}


into

Dim i As Integer = 0
While i < 10
 System.Math.Min(System.Threading.Interlocked.Increment(i),i-1)
End While

Why not?

    Dim i as Integer
    For i = 0 to 9
       Debug.WriteLine(i)
    Next

Or even

Dim i As Integer = 0
While i < 10

 Debug.WriteLine(i) 
 i = i + 1 
End While

Of course, this could be what is happening under the covers anyway.  Why this would be so, I don't have the foggiest.  Let's see if we can find out.

As you probably know, when you compile a .NET app, it gets turned into MSIL (Microsoft Intermediate Language) code, not to machine code (the JIT handles that when you run the app). There is a tool that let's you look at this language if you are so inclined, the MSIL Disassembler.  Being so inclined today, let's see what our for loop looks like in MSIL (the // are comments in the MSIL that indicate the original source code)...

//000028:    for(int i = 0; i<10; i++)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  br.s       IL_0013
//000029:    {
//000030:     Debug.WriteLine(i);
  IL_0004:  ldloc.0
  IL_0005:  box        [mscorlib]System.Int32
  IL_000a:  call       void [System]System.Diagnostics.Debug::WriteLine(object)
//000028:    for(int i = 0; i<10; i++)
  IL_000f:  ldloc.0
  IL_0010:  ldc.i4.1
  IL_0011:  add
  IL_0012:  stloc.0
  IL_0013:  ldloc.0
  IL_0014:  ldc.i4.s   10
  IL_0016:  blt.s      IL_0004
//000029:    {
//000030:     Debug.WriteLine(i);
//000031:    }
//000032:   }
  IL_0018:  ret

You will notice that there is no reference to the Interlock class nor the Math class, which is reassuring.  It's simply looping through and adding 1 to i.  Time to do a little speed test in VB.NET and see what happens when we use the ugly converted code versus the vanilla implementation.

Time (milliseconds)
Iterations Vanilla Converted
10 16 16
100 93 93
1000 1050 1105
10000 15900 26300

Like almost every programming sin, the results are not evident in small samples, but become glaring when you actually start doing something intensive.  In fact running the 10,000 iterations on the converted code caused my little test app to crash occassionally.

The moral? If you use a code converter:
a) Find a good one
b) Don't take it as the gospel truth
c) Clean up after it when it makes boo-boos, especially obvious ones.

Found a couple of goodies while researching this entry.  This is an article about a VS add-in to paste a chunk of C# code as VB code.  Looks pretty cool.

And this is a list of research tools you can download from Microsoft.  Note the reference to F#!

Friday, April 14, 2006 10:53:33 PM (Eastern Standard Time, UTC-05:00)   #     Comments [0]  | 

Theme design by Dean Fiala

Pick a theme: