Reputation: 251
I'm writing some code to generate a procedural map. Some of the steps take much longer than others, and I'm timing each part of the build to see where the bottlenecks are, and to let the user know that the program hasn't stalled on them.
At the moment I have a lot of code that looks like this:
Console.Write("Creating tiles");
var watch = System.Diagnostics.Stopwatch.StartNew();
CreateTiles(); //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
Console.Write("Calculating tile elevations");
var watch = System.Diagnostics.Stopwatch.StartNew();
CalculateTileElevations(); //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
//etc
My question is, is there a way of refactoring this to look something more like the following:
ExecuteTimedFunction(CreateTiles(), "Creating tiles");
ExecuteTimedFunction(CalculateTileElevations(), "Calculating tile elevations");
void ExecuteTimedFunction(Func genericFunction, String logMsg)
{
Console.Write(logMsg);
var watch = System.Diagnostics.Stopwatch.StartNew();
genericFunction();
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
}
Caveat: the return type of all of the functions is void
as they all manipulate a master list of tiles, but not all of the functions have the same number of input parameters (although the majority have 0 parameters so a solution for that case would still be useful)
Upvotes: 1
Views: 281
Reputation: 2470
Your ExecuteTimedFunction
method would look something like this:
public void ExecuteTimedFunction(Action action, string name)
{
Console.Write(name);
var watch = Stopwatch.StartNew();
action();
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
}
Then you can call it in either of the following ways:
ExecuteTimedFunction(MyFunctionWithNoParams, "MyFunc");
ExecuteTimedFunction(() => MyFuncWithParams(p1, p2), "MyFunc2");
Upvotes: 9
Reputation: 16
You can also access the called method details for logging by changing it into something like:
Console.WriteLine($"{action.Method.Name} finished in: {watch.ElapsedMilliseconds / 1000d} s");
Upvotes: 0