TimeSpan timer = new TimeSpan();
DateTime startTime = DateTime.Now;
Type1 rval = DoIt(a, b);
timer += DateTime.Now - startTime;
Firstly, this code is ugly. I'm obviously doing many different things here: timing code, calling a function, storing it's result, etc.... It would be much better if I could wrap the timing code into its own function. So, I esentially want something like:
TimeSpam timer = TimeIt( () => DoIt(a, b) );
The code for TimeIt is simple to write
TimeSpan TimeIt(Action a)
{
DateTime startTime = DateTime.Now;
a.Invoke();
return DateTime.Now - startTime;
}
However, that doesn't save the return value of DoIt, so that is useless for my purposes. I need TimeIt to return the value from DoIt. To do this, I make TimeIt a generic method and have it accept a function instead of an action. I pass the TimeSpan in as a reference argument. The calling code looks like
TimeSpan timeSpan = new TimeSpan();
Type1 rValue = TimeIt(() => DoIt(a, b), ref timeSpan);
The TimeIt function looks like
public static T TimeIt(Func f, ref TimeSpan timeSpan)
{
DateTime startTime = DateTime.Now;
T rVal = f.Invoke();
timeSpan += DateTime.Now - startTime;
}
There, now we have a simple and generic way to time a single method that returns a value. If you wanted to go further, you could create a class that held the TimeSpan value so that you wouldn't have to pass it in as a ref, but this worked for my needs and was clean enough so I stopped here. If I need this code again, I'll refactor it into another library and perhaps into its own class. Until then, I'll enjoy the cleanliness and conciseness.
No comments:
Post a Comment