Lazy Initialization in the CLR 4

by jmorris 18. November 2010 22:38

Lazy initialization or lazy loading, is the idea that the object will not be constructed, created, initialized or loaded until it is absolutely needed.  A common scenario for lazy initialization is a list that stored in a cache is empty until it is accessed, then it is loaded perhaps from a record-set in a database or file and then placed into cached and finally returned back to the caller. If the list is never requested, then the cache is never filled and the application’s working set is smaller. Typically smaller working sets (of memory) mean better perceived performance and happier customers.

System.Lazy<T> provides a (potentially) thread safe wrapper around an object and provides a means of deferring initialization of the core object until it’s requested via Func<T> delegate. Depending upon the constructor called, you can emulate one or more different locking techniques such as doubled checked locking, using a nested class to defer initialization or by doing initialization via a locking mechanism when the object is first accessed. In memory challenged situations, the System.Threading.LazyInitializer class provides static methods for doing thread-safe (potentially) lazy initialization as well.

I included  thread safety “potentially” in parenthesis above because depending upon the constructor overload or method overload used on Lazy<T>  thread safety may or may not be ensured. The reason this is so is to improve performance when thread safety is not required or desired because no synchronization locking is done.

Lazy Initialized Singletons

One of the commonest examples of lazy initialization are implementations of the GOF pattern, the Singleton.  There are several ways to implement the singleton pattern in C# using lazy initialization, from extremely simple to somewhat complex. Each way offers differences in thread synchronization schematics used, the relative thread safety, and the “laziness” of the implementation. Besides the traditional way of implementing singletons,  you can also use one of the new .NET 4 classes System.Lazy<T> or System.Threading.LazyInitializer class.

Their are at least four thread-safe variants of the singleton available to languages targeting the CLR with three of them supporting directly lazy initialization. In a nutshell they are the double-checked locking techniquewhich is broken in Java, but works accurately in C# [1], and full lazy instantiation using a nested inner class with a private static constructor and a reference to an internal static readonly instance of the parent class, and a third version shows thread safe lazy initialization with the caveat of reduced performance since a lock is acquired on all reads. For an in-depth discussion check out Jon Skeet’s excellent article on the topic.

Using the System.Lazy<T> class in .NET 4.0 you can easily implement the singleton pattern in a thread safe, lazy initialized manner that is optimized for performance:

image 

Note that passing in “true” to the constructor makes the initialization thread safe by using double locked schematics described above. If “false” is passed in for isThreadSafe, then no synchronization takes place. You can also use one of the following LazyThreadSafetyMode enumerations in another overloaded constructor call:

  • LazyThreadSafetyMode.None – no synchronization occurs (not thread safe)
  • LazyThreadSafetyMode.Publication – uses Interlocked.CompareExchange
  • LazyThreadSafetyMode.ExecutionAndPublication – uses the C# lock keyword which the CLR interprets as a Monitor (note in Richter’s book he states that it uses double checked locking, but reflector shows only one lock…)

Here is another example using System.Threading.LazyInitializer:

image

Lazy Initialization and Micro Optimizations

Now one might argue that lazy initialization is a premature if not unnecessary micro-optimization. In some respects that is probably true. Singletons, for instance, are only created once for the entire lifetime of an application, typically at start up. However, if you truly need thread safety, lazy initialization then System.Lazy or System.Threading.LazyInitializer are the way to go with .NET 4.

References

  1. CLR via C# by Richter, Jeffry 2010 Microsoft Press
  2. http://en.wikipedia.org/wiki/Lazy_initialization
  3. http://msdn.microsoft.com/en-us/library/dd642331.aspx
  4. http://msdn.microsoft.com/en-us/library/system.threading.lazythreadsafetymode.aspx
  5. http://csharpindepth.com/Articles/General/Singleton.aspx
  6. http://msdn.microsoft.com/en-us/library/system.threading.lazyinitializer.aspx

Tags: , , ,

C#

Refactoring 101: Method Groups

by jmorris 4. November 2010 14:10

C# allows method group conversions, which simplify the invocation of delegates within your code. This is a feature that was added to C# 2.0 and when combined with the Linq extensions provided with .NET 3.5, you can drastically shorten and simplify code.

“Similar to the implicit anonymous method conversions described in §13.5, an implicit conversion exists from a method group (§14.1) to a compatible delegate type. If D is a delegate type, and E is an expression that is classified as a method group, then D is compatible with E if and only if E contains at least one method that is applicable in its normal form (§14.4.2.1) to any argument list (§14.4.1) having types and modifiers matching the parameter types and modifiers of D.”

Basically what the above means that the compiler is “smart” enough to infer the correct overload to call given that their is an adequate candidate method available. For example, given the following two methods:

image

First we can refactor the for loop using lambda expression and the Linq extensions:

image

Then simplify the lambda expression even further by substituting for the implicit method group conversion:

image

Note that the green squiggly lines are hints made by Resharper that the line of code can be refactored. If your not aware of Resharper, it’s a Visual Studio add on that turns VS from a Pinto to Ferrari! If you don’t believe me, try the free trial here. Ok, enough cool-aid and free marketing for resharper…

So, your probably thinking one of three things about now (assuming  you made it this far):

  1. “Big fricken deal, he saved five lines of code”
  2. “Eh, old news. Moving on.”
  3. Wow, that’s fricken awesome dude!”

Personally, I tend towards #3. I am a huge fan  (obviously) of method group conversions because they reduce complexity. They simply make the code easier to read and digest. Code that is easier to read and digest is more easily maintained. Code that is easier to maintained, tends to be of higher quality and less error prone.

References

Tags: , , , ,

Refactoring | Resharper | C#

RIP ANDY IRONS: 1978-2010

by jmorris 3. November 2010 03:25

Bummer for the surfing world, 3x ASP world champion surfer Andy Irons tragically died yesterday reportedly from Dengue fever while returning to Hawaii from Puerto Rica. I never knew him personally, but he was much admired and loved by surfing fans world-wide;  as a fan I have followed his career since he was 17. Unfortunately he leaves a pregnant wife,  father and brother (Bruce Irons another professional surfer) – my regards go out to them. Mahalo Andy, you will be missed!

http://www.aspworldtour.com/2010/11/03/world-champion-andy-irons-passes-away/

Tags: , , ,

RIP

Jeff Morris

Tag cloud

Month List

Page List