Optimal Code / Reading MSIL

  • Thread starter Stefan Hoffmann
  • Start date
S

Stefan Hoffmann

hi @all,

I have these two getter:

public ArrayList I1
{
get
{
if (i1 == null)
{
i1 = new ArrayList();
}
return i1;
}
}

public ArrayList I2
{
get
{
i2 = i2 ?? new ArrayList();
return i2;
}
}


It seems to me, that the MSIL output for the second getter is the
shorter one. But is it also the faster one?

--
.method public hidebysig specialname instance class
[mscorlib]System.Collections.ArrayList
get_I1() cil managed
{
// Code size 41 (0x29)
.maxstack 2
.locals init ([0] class [mscorlib]System.Collections.ArrayList
CS$1$0000,
[1] bool CS$4$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i1
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: newobj instance void
[mscorlib]System.Collections.ArrayList::.ctor()
IL_0018: stfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i1
IL_001d: nop
IL_001e: ldarg.0
IL_001f: ldfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i1
IL_0024: stloc.0
IL_0025: br.s IL_0027

IL_0027: ldloc.0
IL_0028: ret
} // end of method Test::get_I1

.method public hidebysig specialname instance class
[mscorlib]System.Collections.ArrayList
get_I2() cil managed
{
// Code size 33 (0x21)
.maxstack 3
.locals init ([0] class [mscorlib]System.Collections.ArrayList
CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i2
IL_0008: dup
IL_0009: brtrue.s IL_0011

IL_000b: pop
IL_000c: newobj instance void
[mscorlib]System.Collections.ArrayList::.ctor()
IL_0011: stfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i2
IL_0016: ldarg.0
IL_0017: ldfld class [mscorlib]System.Collections.ArrayList
ConsoleApplication1.Test::i2
IL_001c: stloc.0
IL_001d: br.s IL_001f

IL_001f: ldloc.0
IL_0020: ret
} // end of method Test::get_I2
 
M

Marc Gravell

But is it also the faster one?

Well, to answer that you need profiling, not MSIL. But in reality I
don't expect either is your bottleneck; if you are having performance
issues, this almost certainly isn't the cause - concentrate on the
code that "counts", and keep the other code as simple and maintainable
as possible. I personally find the first version more readable, as it
is clear that we only want to change (assign) the field if it is null;
this *might* also make it quicker, but that is just a guess without
profiling.

To be honest, I'd be more interested in replacing ArrayList with a
generic List<T> - removing boxing / casting is likely to have more
benefit than prematurely micro-optimising this code.

Marc
 
P

Pavel Minaev

Stefan Hoffmann said:
hi @all,

I have these two getter:

public ArrayList I1
{
get
{
if (i1 == null)
{
i1 = new ArrayList();
}
return i1;
}
}

public ArrayList I2
{
get
{
i2 = i2 ?? new ArrayList();
return i2;
}
}


It seems to me, that the MSIL output for the second getter is the shorter
one. But is it also the faster one?

Since MSIL is actually JIT-compiled, and .NET JIT knows a lot of
optimizations tricks itself, it may very likely compile to the same native
code. In general, small meaningless differences in MSIL rarely have any
impact on performance.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top