Introduction
Let's say we have a class with these three Attributes:
public bool ValueA { get; set; }
public int ValueB { get; set; }
public string ValueC { get; set; }
Then, if the structure of the method below looks more or less familiar to you, then read on.
public void DoStuff()
{
if (ValueA)
{
if (ValueB < 100)
{
if (ValueC.Length > 10)
{
ASmallBLongC();
}
else
{
ASmallBShortC();
}
}
else
{
if (ValueC.Length > 10)
{
ALargeBLongC();
}
else
{
ALargeBShortC();
}
}
}
else
{
if (ValueB < 100)
{
if (ValueC.Length > 10)
{
NoASmallBLongC();
}
else
{
NoASmallBShortC();
}
}
else
{
if (ValueC.Length > 10)
{
NoALargeBLongC();
}
else
{
NoALargeBShortC();
}
}
}
}
The method shown here is an exposed method that figures out which exact method to call, based on the state of the class' attributes. More often than not, this type of code nests deeper than just the three attributes used in this example.
It is also quite often the case that the attributes get set fewer times than what the actual method executes for.
Background
After spending loads of time in code such as this to ensure that the flow logic is correct, we started thinking whether there isn't a more optimal way of coding this? Typically, in our use, we would create a class, set the Attributes and then get the class to perform a method (or a number of methods) many times over.
After a bit of experimentation, we opted to make use of a delegate that we assign once, only when any of the attributes change, and we were able to get the code to execute a bit faster.
The Solution
The improved solution saw us introduce a delegate such as this (one that would represent the signature of the method being called:
public delegate void DoStuffDelegate();
Our DoStuff
method was then changed to be a delegate
, like this:
public DoStuffDelegate DoStuff;
and our original DoStuff()
method was renamed and changed to assign the delegate
to the correct method, based on the values of the Attributes.
So we changed this:
NoALargeBLongC();
to this:
DoStuff = ASmallBLongC;
Our tests have shown that if the DoStuff
gets called 10 million times, we get an execution time of 340 MS and using the revised class where we assign the delegate
, this came down to 42 MS which is a noticeable difference.
Points of Interest
This is not something that will work for every case, I would recommend doing this only in cases where you set attributes of classes not that often, but you have code that forks out that has to be executed much more.
I have included a sample project with the two classes in it, so you can see the whole sample working. Happy to hear of any improvements that can be made.
History
- 2nd December, 2015: Initial version