5

In my c# program, my requirement is to calculate a timespan for business logic execution that is inside a foreach loop I have to store time span.

I am using following code

for (int i = 0; i < 100; i++)
{
    DateTime start= DateTime.Now; 
    // Business logic
    DateTime end= DateTime.Now; 
    TimeSpan time = start.Subtract(end);
    // Save timespan in log file
}

Please correct me whether I am using right code, or do I need to modify for better performance and result.

Fischermaen
  • 12,238
  • 2
  • 39
  • 56
Hemant Kothiyal
  • 4,092
  • 19
  • 61
  • 80
  • 2
    I think you would be more interested in [Stopwatch](http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) – V4Vendetta Dec 29 '11 at 06:56
  • Using `DateTime.Now` instead of `DateTime.UtcNow` is almost never the right thing to do (but StopWatch is better in this case anyway). – Ian Mercer Dec 29 '11 at 07:00
  • Possible duplicate of [Is DateTime.Now the best way to measure a function's performance?](https://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance) – Michael Freidgeim Nov 30 '18 at 01:45

4 Answers4

19

You should use a Stopwatch. The Stopwatch is much more accurate for time measurement than the wall time clock.

var sw = Stopwatch.StartNew();
// business logic
sw.Stop();
TimeSpan time = sw.Elapsed;
Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108
  • Thanks, great information, further two more questions 1. As i am using for loop hence no need to create instance of Stopwatch inside loop everytime (am i right?) 2. I want total time spend in second if less than 1 minute otherwise in minutes if greater than 1 minute, any information on that? – Hemant Kothiyal Dec 29 '11 at 07:05
2

The easiest way would be to:

TimeSpan time = DateTime.Now - start;

Alternatively, you could use a stopwatch which gives more accurate results. See http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx for how to work with a stopwatch.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
1

To answer your follow up questions, (1) you are correct, you do not need to reinstantiate a StopWatch every iteration. You just need to use the restart method, like so:

Stopwatch sw = new Stopwatch();
sw.Start(); // To initialize
for (int i = 0; i < 100; i++)
{
    sw.Restart();
    // Business logic 
    TimeSpan time = sw.Elapsed;
    // Save timespan in log file
}

(2) You would probably have to write a few lines of code to return the value in seconds if less than one minute, and minutes if greater than, but here would be an example of doing that (assume this is the line right after saving the timespan from the above example):

TimeSpan time = sw.Elapsed;
int iSecondsOrMinutes = time.TotalSeconds < 60 ? time.Seconds : (int)time.TotalMinutes;

This example uses a Ternary Operator to save the integer for the amount of minutes or seconds.

Aaron Deming
  • 1,015
  • 10
  • 12
1

It looks like you're using the timespan to measure performance. Your code is fine, however you should be aware that DateTimes are only so precise (about 10-15ms on most machines -- see the "Useless Timer Mechanism" section here for an explanation).

DateTimes are also not contiguous; what if the first DateTime is retrieved just before daylight savings time kicks in, and the latter one just after? An operation that takes one second could show up as taking an hour, or even negative time. Even with all times in UTC, there's potential problems when the user changes the time manually, or jumps caused by the computer going to sleep and waking up, etc.

A better alternative would be to use the Stopwatch class, which is designed for this sort of thing and uses a high-precision timer internally (via the QueryPerformanceCounter() Win32 function).

Cameron
  • 96,106
  • 25
  • 196
  • 225