开发者

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));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜