Also available at

Also available at my website http://tosh.me/ and on Twitter @toshafanasiev

Monday, 25 October 2010

Singleton Pattern in C#

The Singleton Pattern is a strategy that provides a single instance of a certain class for an entire application ( strictly speaking in .NET it's per Application Domain ); and ensures that any reference to an instance of that class in that application is to that single instance. This approach can help maintain consistency in multithreaded scenarios and simplify resource sharing while requiring a minimum of not-very-object-oriented static-heavy code.
This is one of the Design Patterns attributed to the Gang of Four.
This pattern is typically implemented using lazy instantiation - only creating the instance the first time it is referenced - which can be achieved using double-checked locking to minimise the performance overhead of thread synchronisation, as follows:
sealed class SingletonOne {
  private SingletonOne() {
    // constructor logic
  }
  private static SingletonOne s_instance;
  private static object s_padlock = new Object();
  public static SingletonOne Instance {
    get {
      if ( s_instance == null ) {
        lock( s_padlock ) {
          if ( s_instance == null ) {
            s_instance = new SingletonOne(); 
          }
        }
      }
      return s_instance;
    }
  }
}

There is nothing actually wrong with this ( as opposed to the examples you see that implement
no thread-synchronisation at all ) but it is more handmade and marginally less efficient than the following implementation which takes advantage of some built-in CLR features:
sealed class SingletonTwo {
  private SingletonTwo() {
    // constructor logic
  }
  public static readonly SingletonTwo Instance = new SingletonTwo();
}

What this second implementation gives you is a single instance that is thread-safely single ( ensured by the CLR's initialisation of static fields and enforcement of the readonly attribute ) but without the overhead of the null check or even the accessor call - this field access is about 20 times faster than the above property access ( see complete program at the end of the post ); as well as far less code to write, maintain, curse etc.
One thing to be aware of, however, is the timing of this new initialisation scheme. Disassembling the program with ILDasm.exe shows the class declaration as follows:
.class private auto ansi sealed beforefieldinit SingletonTwo
  extends [mscorlib]System.Object

The point of interest here being the beforefieldinit attribute - this tells the CLR to ensure that the field is initialised at some point before the field is accessed; in other words, it could occur quite a while before - at any point when the CLR deems appropriate based on factors such as CPU load ( there's a very good article on this here: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx ).
If the timing of a singleton's initialisation code is important and it should run just before first access, not at some arbitrary point earlier on; this can be achieved by instructing the compiler to omit the beforefieldinit attribute, which in C# is as simple as defining a class constructor ( sometimes called a static constructor ). The following class definition shows this in action:
sealed class SingletonThree {
  private SingletonThree() {
    // constructor logic
  }
  public static readonly SingletonThree Instance;
  static SingletonThree() {
    Instance = new SingletonThree();
  }
}

This class definition disassembles to the following:
.class private auto ansi sealed SingletonThree
  extends [mscorlib]System.Object

( note the lack of beforefieldinit; note also that it's irrelevant what the class constructor actually does - its presence signals the compiler to omit that attribute )
So all in all: cleaner, quicker code and control over timing - what's not to like?
By the way, for my money the best reference of on MSIL internals such as beforefieldinit is Inside Microsoft .NET IL Assembler by Serge Lidin, the guy behind IL itself.

Below is a complete program that includes the performance testing from which I arrived at the property access vs. field access figures:
using System;
using System.Diagnostics;

sealed class SingletonOne {
  private SingletonOne() {
    // constructor logic
  }
  private static SingletonOne s_instance;
  private static object s_padlock = new Object();
  public static SingletonOne Instance {
    get {
      if ( s_instance == null ) {
        lock( s_padlock ) {
          if ( s_instance == null ) {
            s_instance = new SingletonOne(); 
          }
        }
      }
      return s_instance;
    }
  }
}

sealed class SingletonTwo {
  private SingletonTwo() {
    // constructor logic
  }
  public static readonly SingletonTwo Instance = new SingletonTwo();
}

sealed class SingletonThree {
  private SingletonThree() {
    // constructor logic
  }
  public static readonly SingletonThree Instance;
  static SingletonThree() {
    Instance = new SingletonThree();
  }
}

class test {
  static void Main() {
    Console.WriteLine(
      "Testing SingletonOne: {0}", SingletonOne.Instance == SingletonOne.Instance
    );
    Console.WriteLine(
      "Testing SingletonTwo: {0}", SingletonTwo.Instance == SingletonTwo.Instance
    );
    Console.WriteLine(
      "Testing SingletonThree: {0}", SingletonThree.Instance == SingletonThree.Instance
    );

    // performance testing
    const int ITERATIONS = 50000000;

    // test property access
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Stopwatch timerOne = Stopwatch.StartNew();
    for ( int i=0; i<ITERATIONS; i++ ) {
      SingletonOne s = SingletonOne.Instance;
    }
    timerOne.Stop();

    // test field access
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Stopwatch timerTwo = Stopwatch.StartNew();
    for ( int i=0; i<ITERATIONS; i++ ) {
      SingletonTwo s = SingletonTwo.Instance;
    }
    timerTwo.Stop();

    Console.WriteLine(
      "Property access: {0} ms", timerOne.ElapsedMilliseconds / ( double ) ITERATIONS
    );
    Console.WriteLine(
      "Field access: {0} ms", timerTwo.ElapsedMilliseconds / ( double ) ITERATIONS
    );
  }
}

Tuesday, 12 October 2010

Overflow checking in VB.NET

I am currently porting a VB6 application to VB.NET and having run the project through the VS2008 conversion wizard, I am now trying to fix the as yet unknowable number of errors that it could not resolve. One of these relates to truncation of integers to yield hi- or lo- words.
The hi-word was ok - VB.NET gives you shift operators so the following is possible.

Dim i As Int32
'...
Dim s As Short
s = i >> 16

Ordinarily ( i.e. in C# ) the lo-word would not pose a problem either as an unchecked ( the default ) conversion from int to short would yield the correct result, simply discarding the upper two bytes

static short LoWord( int val ) {
  return ( short ) val;
}

This can be confirmed by disassembling the compiled IL code ( using ILDasm.exe )

.method private hidebysig static int16  LoWord(int32 val) cil managed
{
  // Code size       8 (0x8)
  .maxstack  1
  .locals init (int16 V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  conv.i2
  IL_0003:  stloc.0
  IL_0004:  br.s       IL_0006
  IL_0006:  ldloc.0
  IL_0007:  ret
} // end of method prog::LoWord

The conv.i2 instruction labelled IL_0002 does not perform overflow checking. However, a similarly written function in VB.NET does not behave the same way:

Function LoWordVb( ByVal i As Integer ) As Short
  Return CShort( i )
End Function

This disassembles to:

.method public static int16  LoWordVb(int32 i) cil managed
{
  // Code size       7 (0x7)
  .maxstack  1
  .locals init (int16 V_0)
  IL_0000:  ldarg.0
  IL_0001:  conv.ovf.i2
  IL_0002:  stloc.0
  IL_0003:  br.s       IL_0005
  IL_0005:  ldloc.0
  IL_0006:  ret
} // end of method prog::LoWordVb

Which uses the same overflow checking conv.ovf.i2 instruction as the following C# function:

  static short LoWordChecked( int val ) {
    checked {
      return ( short ) val;
    }
  }

Which disassembles to:

.method private hidebysig static int16  LoWordChecked(int32 val) cil managed
{
  // Code size       9 (0x9)
  .maxstack  1
  .locals init (int16 V_0)
  IL_0000:  nop
  IL_0001:  nop
  IL_0002:  ldarg.0
  IL_0003:  conv.ovf.i2
  IL_0004:  stloc.0
  IL_0005:  br.s       IL_0007
  IL_0007:  ldloc.0
  IL_0008:  ret
} // end of method prog::LoWordChecked

( There are a few details that you need to be aware of when using overflow checking in C# which I won't go into - there's a very comprehensive and well written post on the subject here: http://www.codeproject.com/KB/cs/overflow_checking.aspx )
So, while C# offers extremely granular control of overflow checking by means of the checked construct, VB.NET does not ( that I could find out about ), so short of controlling this behaviour globally for the entire application ( something which I am a little wary of doing ), there's no immediately obvious way to perform this apparently simple task.
My solution was to copy, memory wise, the lower bytes of the Int32 to the Int16; this may not be the most elegant or efficient solution, but it does work.
VB.NET does not offer any of the syntax-level pointer manipulation that C# does ( once you use the terrifyingly named 'unsafe' construct and compiler switch ), however the .NET BCL makes everything you need available via the System.Runtime.InteropServices namespace in Mscorlib.dll - once you get to know these tools you can use them from any CLR targeting language.
First you need an instance of the GCHandle structure for the managed object you are copying from ( in this case it will have to be a boxed copy of the Int32 ), you obtain this as follows:

Dim i As Int32
' ....
Dim h As GCHandle = GCHandle.Alloc( i, GCHandleType.Pinned )

And the GCHandle must be cleaned up responsibly to prevent resource leaks ( yes, in .NET ) - I suggest a try/finally block immediately after allocation that calls h.Free() in the finally clause - ensuring that it's freed. 
One thing that may occur to you is that passing a value type instance such as Int32 as a parameter of type Object will result in a box operation, generating a reference that is never explicitly held onto by the calling function and that this could cause problems - this is not the case as both the Pinned and Normal members of the GCHandleType enumeration result in the GCHandle instance preventing the reference passed in from being collected until the handle is itself freed. Using Pinned rather than Normal gives our code the opportunity to use the address of the instance without worrying about it being moved by the garbage collector.
The next step is using the Marshal class to copy from memory to a managed instance

Dim s As Short
Dim o As Object
o = Marshal.PtrToStructure( h.AddrOfPinnedObject(), GetType( Short ) )
' simple unbox
s = CShort( o )

That's it! These elements can be put together in a function as follows ( a complete program is available at the end of the post ):

Imports System.Runtime.InteropServices
'....
Function LoWordVbUnchecked( ByVal i As Integer ) As Short
  Dim s As Short
  Dim h As GCHandle = GCHandle.Alloc( i, GCHandleType.Pinned )
  Try
    Dim o As Object
    o = Marshal.PtrToStructure( h.AddrOfPinnedObject(), GetType( Short ) )
    s = CShort( o )
  Finally
    h.Free()
  End Try
  Return s
End Function

A lot of words, you might think, but I think that this example serves to cover many interesting aspects of developing code for the .NET CLR.

Complete program:

'author: Tosh Afanasiev ( http://tosh.me/ )

Imports System
Imports System.Runtime.InteropServices

Module prog

  Public Sub Main()
    Dim i As Int32 = &Haaaabbbb
    Dim s As Int16 = i >> 16
    Console.WriteLine( "i: {0:x}", i )
    Console.WriteLine( "hi: {0:x}", s )
    Console.WriteLine( "using LoWordVb causes an OverflowException for this value" )
    Try
      s = LoWordVb( i )
    Catch ex As OverflowException
      Console.WriteLine( "told you: {0}", ex )
    End Try
    Console.WriteLine( "LoWordVbUnchecked is ok though" )
    s = LoWordVbUnchecked( i )
    Console.WriteLine( "lo: {0:x}", s )
  End Sub

  Function LoWordVb( ByVal i As Integer ) As Short
    Return CShort( i )
  End Function

  Function LoWordVbUnchecked( ByVal i As Integer ) As Short
    Dim s As Short
    Dim h As GCHandle = GCHandle.Alloc( i, GCHandleType.Pinned )
    Try
      Dim o As Object
      o = Marshal.PtrToStructure( h.AddrOfPinnedObject(), GetType( Short ) )
      s = CShort( o )
    Finally
      h.Free()
    End Try
    Return s
  End Function

End Module