I'm writing a computationally intensive program with VB.NET 2010 and I wish to optimise speed. I find that the operators AndAlso
and OrElse
are anomalously slow if the result of the operation is assigned to a class-level variable. For example, while the statements
a = _b AndAlso _c
_a = a
take about 6 machine cycles between them in the compiled exe, the single statement
_a = _b AndAlso _c
takes about 80 machine cycles. Here _a
, _b
and _c
are Private Boolean variables of Form1
, and the statements in question are in an instance procedure of Form1
, of which a
is a local Boolean variable.
I cannot find why the single statement takes so long. I have explored it using NetReflector down to the level of the CIL code, which looks good:
Instruction Explanation Stack
00: ldarg.0 Push Me (ref to current inst of Form1) Me
01: ldarg.0 Push Me Me, Me
02: ldfld bool Form1::_b Pop Me, read _b and push it _b, Me
07: brfalse.s 11 Pop _b; if false, branch to 11 Me
09: ldarg.0 (_b true) Push Me Me, Me
0a: ldfld bool Form1::_c (_b true) Pop Me, read _c and push it _c, Me
0f: brtrue.s 14 (_b true) Pop _c; if true, branch to 14 Me
11: ldc.i4.0 (_b, _c not both true) Push result 0 result, Me
12: br.s 15 Jump unconditionally to 15 result, Me
-----
14: ldc.i4.1 (_b, _c both true) Push result 1 result, Me
15: stfld bool Form1::_a Pop result and Me; write result to _a (empty)
1a:
Can anyone shed any light on why the statement _a = _b AndAlso _c
takes 80 machine cycles instead of the predicted 5 or so?
I'm using Windows XP with .NET 4.0 and Visual Studio Express 2010. I measured the times with a frankly dirty snippet of my own which basically uses a Stopwatch object to time a For-Next loop with 1000 iterations containing the code in question and compare it with an empty For-Next loop; it includes one useless instruction in both loops to waste a few cycles and prevent processor stalling. Crude but good enough for my purposes.