Today I want to revue the history of property lazy-initialization I used over the years.
Further more, I decided to "measure" if I'm changing for good and is the pattern I use last is the best, the most optimized one.
First, in the old good years I used the "standard" lazy-initialization pattern:
public string First {
get {
if (_first == null) {
_first = "Initialized";
}
return _first;
}
}
Then, at some point I realized I could use by my opinion better pattern:
public string Second {
get {
return (_second != null) ? _second : (_second = "Initialized");
}
}
Last, I found out the good usage of "??" operator on property lazy-initialization and here is my latest pattern:
public string Last {
get {
return _last ?? (_last = "Initialized");
}
}
So, in code the last one looks better, shorter and more optimized like.
But, is that the real case. I decided to check out the generated IL and here are the results:
First :
.method public hidebysig specialname instance string
get_First() cil managed
{
// Code size 41 (0x29)
.maxstack 2
.locals init ([0] string CS$1$0000,
[1] bool CS$4$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_first
IL_0007: ldnull
IL_0008: ceq
IL_000a: ldc.i4.0
IL_000b: ceq
IL_000d: stloc.1
IL_000e: ldloc.1
IL_000f: brtrue.s IL_001e
IL_0011: nop
IL_0012: ldarg.0
IL_0013: ldstr "Initialized"
IL_0018: stfld string Artem.WebSite.Models.Test::_first
IL_001d: nop
IL_001e: ldarg.0
IL_001f: ldfld string Artem.WebSite.Models.Test::_first
IL_0024: stloc.0
IL_0025: br.s IL_0027
IL_0027: ldloc.0
IL_0028: ret
} // end of method Test::get_First
Second:
.method public hidebysig specialname instance string
get_Second() cil managed
{
// Code size 36 (0x24)
.maxstack 3
.locals init ([0] string CS$1$0000,
[1] string CS$0$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_second
IL_0007: brtrue.s IL_0019
IL_0009: ldarg.0
IL_000a: ldstr "Initialized"
IL_000f: dup
IL_0010: stloc.1
IL_0011: stfld string Artem.WebSite.Models.Test::_second
IL_0016: ldloc.1
IL_0017: br.s IL_001f
IL_0019: ldarg.0
IL_001a: ldfld string Artem.WebSite.Models.Test::_second
IL_001f: stloc.0
IL_0020: br.s IL_0022
IL_0022: ldloc.0
IL_0023: ret
} // end of method Test::get_Second
Last:
.method public hidebysig specialname instance string
get_Last() cil managed
{
// Code size 30 (0x1e)
.maxstack 3
.locals init ([0] string CS$1$0000,
[1] string CS$0$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_last
IL_0007: dup
IL_0008: brtrue.s IL_0019
IL_000a: pop
IL_000b: ldarg.0
IL_000c: ldstr "Initialized"
IL_0011: dup
IL_0012: stloc.1
IL_0013: stfld string Artem.WebSite.Models.Test::_last
IL_0018: ldloc.1
IL_0019: stloc.0
IL_001a: br.s IL_001c
IL_001c: ldloc.0
IL_001d: ret
} // end of method Test::get_Last
Less lines in IL for every next pattern, which should means better and more optimized code.
Great. I'm happy now and I'm sure my lazy-initialization pattern has changed for good
Hope this helps...
Regards
Posted
02-13-2009 10:37
by
velio