views:

1449

answers:

6

What is the most exact way of seeing how long something, for example a method call, took in code?

The easiest and quickest I would guess is this:

DateTime start = DateTime.Now;
{
    // Do some work
}
TimeSpan timeItTook = DateTime.Now - start;

But how exact is this? Are there better ways?

+2  A: 

Use the Stopwatch class

Mehrdad Afshari
Downvoters: we'll be happy to know what's wrong!
Mehrdad Afshari
+22  A: 

A better way is to use the Stopwatch class:

Stopwatch sw = new Stopwatch();

sw.Start();

// ...

sw.Stop();

Console.WriteLine("Elapsed={0}",sw.Elapsed);
Philippe Leybaert
Cool, had no idea this class even existed.
Svish
If you need to know the resolution of the Stopwatch timings on a particular machine then you can use the Stopwatch.Frequency property.
LukeH
@Luke Good tip!
Svish
+2  A: 

System.Diagnostics.Stopwatch is designed for this task.

Greco
Downvoted for what?!?
Greco
See the comments on the question above, and you'll see why.
Philippe Leybaert
A: 

Yes there are some function on Windows kernel

 [System.Runtime.InteropServices.DllImport("KERNEL32")]
 private static extern bool QueryPerformanceCounter(  ref long lpPerformanceCount);

 [System.Runtime.InteropServices.DllImport("KERNEL32")]
 private static extern bool QueryPerformanceFrequency( ref long lpFrequency);


public static float CurrentSecond
     {
      get
      {
       long current = 0;
       QueryPerformanceCounter(ref current);
       long frequency = 0;
       QueryPerformanceFrequency(ref frequency);
       return (float) current / (float) frequency;
      }
     }
pixel3cs
+11  A: 

As others have said, Stopwatch is a good class to use here. You can wrap it in a helpful method:

public static TimeSpan Time(Action action)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    action();
    stopwatch.Stop();
    return stopwatch.Elapsed;
}

(Note the use of Stopwatch.StartNew(). I prefer this to creating a Stopwatch and then calling Start() in terms of simplicity.) Obviously this incurs the hit of invoking a delegate, but in the vast majority of cases that won't be relevant. You'd then write:

TimeSpan time = StopwatchUtil.Time(() =>
{
    // Do some work
});

You could even make an ITimer interface for this, with implementations of StopwatchTimer, CpuTimer etc where available.

Jon Skeet
Nice idea with the helper method.
Noldorin
Nice indeed =)
Svish
Downvoters: please comment...
Jon Skeet
I like the idea, but the ()=> syntax always rubs me the wrong way, not sure why (I didn't downvote, just commenting).
GWLlosa
I upvoted :), nice solution you presented. As for the downvoting: I think one person downvoted every answer in here
Philippe Leybaert
@GWLlosa: Would you prefer a "delegate { }" version, out of interest? @activa: That's weird... then again, people do vote weirdly sometimes.
Jon Skeet
I think real Jon Skeet does not have time to post answers on SO. All you guys care all about reputation, not for the best answer. Some SO users may have 2 accounts and they vote for themselves but from another account. Also some users read the best answer then answer with the same solution, the scope is to receive votes from others. What is better than QueryPerformanceFrequency ???
pixel3cs
pixel3cs: That sounds distinctly like sour grapes to me. To be clear: are you accusing me of vote fraud? Are you accusing me of not being "the real Jon Skeet"? As for why Stopwatch is better than using P/Invoke: It's simpler to use, but gets the same results.
Jon Skeet
It's a shame to accuse someone like Jon Skeet of vote fraud! People like him must be respected for what they do for the progrmming community.don't care for these Jon, People Love you and trust you.
Abdullah BaMusa
A: 

Stopwatch is fine, but loop the work 10^6 times, then divide by 10^6. You'll get a lot more precision.

Mike Dunlavey
Good point, but would still need something to take the time on those 10^6 times :)
Svish
Put Stopwatch around the whole thing. I thought that was clear.
Mike Dunlavey