How can I neatly time if something works?
Currently I am using the following:
开发者_开发问答Stopwatch stopWatchB = new Stopwatch();
stopWatchB.Start();
_callIndex.Test = _callTable.Get(u => u.PartitionKey == _callIndex.PageMeta.User & u.RowKey == "A");
stopWatchB.Stop();
em1 = stopWatchB.ElapsedMilliseconds;
My code works great but looks so messy. Stopwatches starting and stopping :-( Is there any way that I could clean this up. Note that I can't change the .Get() method and the data returned to _callIndex.Test is a class called Test that has multiple fields.
Well, to start with you can use:
Stopwatch stopWatchB = Stopwatch.StartNew();
You could also take the ElapsedMilliseconds
without stopping it first, if you wanted:
Stopwatch stopWatchB = Stopwatch.StartNew();
_callIndex.Test = _callTable.Get(
u => u.PartitionKey == _callIndex.PageMeta.User & u.RowKey == "A");
em1 = stopWatchB.ElapsedMilliseconds;
That's a bit simpler. Alternatively, you could create a helper method:
public static TimeSpan Time(Action action)
{
Stopwatch stopwatch = Stopwatch.StartNew();
action();
return stopwatch.Elapsed;
}
Then:
em1 = StopwatchHelper.Time(() => {
_callIndex.Test = _callTable.Get(
u => u.PartitionKey == _callIndex.PageMeta.User & u.RowKey == "A");
}).TotalMilliseconds;
I use this to do "benchmark"
for using it:
using(var b = new bench())
{
//stuff
em1 = b.ElapsedMilliseconds;
}
///
class bench : Stopwatch, IDisposable
{
private static bool enabled = true;
public static bool Enabled
{
get { return enabled; }
set { enabled = value; }
}
private string func;
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
public bench()
{
begin("", false, false);
}
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
/// <param name="showStack">if set to <c>true</c> [show stack].</param>
public bench(bool showStack)
{
begin("", showStack, false);
}
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
/// <param name="showStack">if set to <c>true</c> [show stack].</param>
/// <param name="showStart">if set to <c>true</c> [show start].</param>
public bench(bool showStack, bool showStart)
{
begin("", showStack, showStart);
}
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
/// <param name="func">The func.</param>
public bench(String func)
{
begin(func, false, false);
}
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
/// <param name="func">The func.</param>
/// <param name="showStack">if set to <c>true</c> [show stack].</param>
public bench(String func, bool showStack)
{
begin(func, showStack, false);
}
/// <summary>
/// Initializes a new instance of the <see cref="bench"/> class.
/// </summary>
/// <param name="func">The func.</param>
/// <param name="showStack">if set to <c>true</c> [show stack].</param>
/// <param name="showStart">if set to <c>true</c> [show start].</param>
public bench(String func, bool showStack, bool showStart)
{
begin(func, showStack, showStart);
}
/// <summary>
/// Begins the specified func.
/// </summary>
/// <param name="func">The func.</param>
/// <param name="showStack">if set to <c>true</c> [show stack].</param>
/// <param name="showStart">if set to <c>true</c> [show start].</param>
private void begin(String func, bool showStack, bool showStart)
{
if (bench.Enabled)
{
this.func = func;
if (showStack || showStart)
Debug.WriteLine("Start " + func);
if (showStack)
Debug.WriteLine("Stack: " + Environment.StackTrace);
this.Start();
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (bench.Enabled || this.IsRunning)
{
this.Stop();
if (bench.Enabled)
{
Debug.WriteLine("Stop " + func + " " + Elapsed.TotalSeconds.ToString("0.#######") + " seconds");
}
}
}
}
Create a class that implements IDisposable, and starts a stopwatch on creation, stopping it when disposed.
You can create a class that manages such items, as in my code here:
https://stackoverflow.com/questions/6410569/speeding-up-performance-monitoring-code
It does quite a bit more than you ask (handling timing 'child' code and rendering timing values), however you can hopefully get the basic idea.
EDIT: For a simple example, see @Fredou's answer.
You can write the class which starts Stopwatch in the constructor and stops in the Dispose() (obviously you have to implement IDisposable).
using (var profiler = new PerformanceProfiler(out elapsedMilliseconds)
{
// profiled action code ...
}
Debug.WriteLine(elapsedMilliseconds.ToString(CultureInfo.CurrentCulture));
精彩评论