views:

6274

answers:

13

I need to find a bottleneck and need to accurately as possible measure time.

Is the following Code Snippet the best way to measure the performance?

DateTime startTime = DateTime.Now;

// Some Execution Process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
+10  A: 

The stopwatch functionality would be better (higher precision). I'd also recommend just downloading one of the popular profilers, though (DotTrace and ANTS are the ones I've used the most... the free trial for DotTrace is fully functional and doesn't nag like some of the others).

jsight
A: 

That's the way I do it, because it's quick and dirty. The "right" way might be to use performance counters

edit: forgot about StopWatch. ignore me! :D

hometoast
+233  A: 

No, it's not, use the Stopwatch (in System.Diagnostics)

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Stopwatch automatically checks for the existence of high-precision timers.

It is worth mentioning that DateTime.Now often is quite a bit slower than DateTime.UtcNow due to the work that has to be done with timezones, DST and such.

DateTime.UtcNow typically has a resolution of 15ms. See John Chapman's blog post about DateTime.Now precision for a great summary.

Interesting trivia: The stopwatch falls back on DateTime.UtcNow if your hardware doesn't support a high frequency counter. You can check to see if Stopwatch utilizes hardware to achieve high precision by looking at the static field Stopwatch.IsHighResolution.

Markus Olsson
Very nice tip...
CSharpAtl
+8  A: 

Use the System.Diagnostics.Stopwatch class.

Stopwatch sw = new Stopwatch();
sw.Start();

// Do some code.

sw.Stop();

// sw.ElapsedMilliseconds = the time your "do some code" took.
rp
A: 

I've done very little of this sort of performance checking (I tend to just think "this is slow, make it faster") so I have pretty much always gone with this.

A google does reveal a lot of resources/articles for performance checking.

Many mention using pinvoke to get performance information. A lot of the materials I study only really mention using perfmon..

Edit:

Seen the talks of StopWatch.. Nice! I have learned something :)

This looks like a good article

Rob Cooper
+51  A: 
Simucal
Does ANTS work with F# yet?
Jon Harrop
+2  A: 

@Sean Chambers

FYI, the .NET Timer class is not for diagnostics, it generates events at a preset interval, like this (from MSDN):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

So this really doesn't help you know how long something took, just that a certain amount of time has passed.

The timer is also exposed as a control in System.Windows.Forms... you can find it in your designer tool box in VS05/VS08

Adam Haile
+5  A: 

Ditto Stopwatch, it is way better.

Regarding performance measuring you should also check whether your "// Some Execution Process" is a very short process.

Also bear in mind that the first run of your "// Some Execution Process" might be way slower than subsequent runs.

I typically test a method by running it 1000 times or 1000000 times in a loop and I get much more accurate data than running it once.

Andrei Rinea
+6  A: 

It's useful to push your benchmarking code into a utility class/method. The StopWatch class does not need to be Disposed or Stopped on error. So, the simplest code to time some action is

public partial class With
{
    public static long Benchmark(Action action)
    {
        var stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
}

Sample calling code

public void Execute(Action action)
{
    var time = With.Benchmark(action);
    log.DebugFormat(“Did action in {0} ms.”, time);
}

Here is the extension method version

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

And sample calling code

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}
Anthony Mastrean
A: 

By the way, if you are not looking for something quick and dirty performance counters can be used.

Jonathan C Dickinson
+1  A: 

I just found a post in Vance Morrison's blog about a CodeTimer class he wrote that makes using StopWatch easier and does some neat stuff on the side.

OwenP
+1  A: 

Visual Studio Team System has some features that may help with this problem. Essentially you can write unit tests and mix them in different scenarios to run against your software as part of a stress or load test. This may help to identify areas of code that impact your applications performance the most.

Microsoft Patterns and Practices have some guidance here.

Iain
+4  A: 

These are all great ways to measure time, but that is only a very indirect way to find bottleneck(s).

The most direct way to find a bottneck in a thread is to get it running, and while it is doing whatever makes you wait, halt it with a pause or break key. Do this several times. If your bottleneck takes X% of time, X% is the probability that you will catch it in the act on each snapshot.

Here's a more complete explanation of how and why it works

Mike Dunlavey