Naveen Kumar V
Naveen Kumar V

Reputation: 2809

Why ElapsedTicks of Stopwatch in C# is collapsed?

I want to know why the ElapsedTicks value(s) difference is changing just because of changing the region.

Code

 Stopwatch timer = new Stopwatch( );
 #region "TimeCheck1"
 timer.Start( );
 string s1 = "HelloWorld";
 int length = s1.Length;
 int subLength = length / 2;
 string sA = s1.Substring(0, subLength);
 string sB = s1.Substring(subLength, subLength);
 timer.Stop( );
 Console.WriteLine("String: " + s1 + " Sub1: " + sA + " Sub2: " + sB + " Timer: " + timer.ElapsedTicks);
 #endregion "TimeCheck1"

 #region "TimeCheck2"
 timer.Start( );
 string s2 = "HelloWorld";
 int length2 = s2.Length;
 int subLength2 = length2 / 2;
 string s2A = subStr(s2, 0, subLength2);
 string s2B = subStr(s2, subLength2, subLength2);
 timer.Stop( );
 Console.WriteLine("String: " + s2 + " Sub1: " + s2A + " Sub2: " + s2B + " Timer: " + timer.ElapsedTicks);
 #endregion "TimeCheck2"

Output 1

String: HelloWorld Sub1: Hello Sub2: World Timer: 12
String: HelloWorld Sub1: Hello Sub2: World Timer: 639

Output 2

after interchanging regions TimeCheck1 and TimeCheck2
String: HelloWorld Sub1: Hello Sub2: World Timer: 826
String: HelloWorld Sub1: Hello Sub2: World Timer: 828

Why this difference occurs? I'm too confused here.

Edit ( I hope, this method is not an issue)

private static string subStr( string str, int index, int len ) {
    string sub = "";
    int c = index;
    len = index + len;
    while( c != len ) {
        sub += str[ c ];
        c++;
    }
    return sub;
}

Upvotes: 1

Views: 182

Answers (2)

Steve
Steve

Reputation: 216263

You are using the StopWatch wrongly. You should call Restart() on the second call, not Start(). If you change it then you get consistent result in your measures

From MSDN StopWatch.Start

When a Stopwatch instance measures more than one interval, the Start method resumes measuring time from the current elapsed time value. A Stopwatch instance calculates and retains the cumulative elapsed time across multiple time intervals, until the instance is reset. Use the Reset method before calling Start to clear the cumulative elapsed time in a Stopwatch instance. Use the Restart method to Reset and Start the Stopwatch with a single command.

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

 #region "TimeCheck1"
 .....
 #endregion "TimeCheck1"

 timer.Restart( );
 #region "TimeCheck2" 
 ....
 #endregion

Now if you invert the regions the measurements are coehrent. And you can see that your subStr takes a performance hit on its first run.

Upvotes: 4

kevintjuh93
kevintjuh93

Reputation: 1010

Because the Stopwatch depends on OS and hardware.

From Stopwatch.IsHighResolution

The timer used by the Stopwatch class depends on the system hardware and operating system. IsHighResolution is true if the Stopwatch timer is based on a high-resolution performance counter. Otherwise, IsHighResolution is false, which indicates that the Stopwatch timer is based on the system timer.

The more ticks per interval, the higher the resolution. Which means the Stopwatch will be much more accurate.

Edit: As CodeCaster mentioned, sometimes the Stopwatch has to warm-up. Probably because it uses hardware in the High Resolution state. From my experience I can tell you it is true. Try starting only one Stopwatch. And calculate the difference between ticks (current - start). It might also help to add a sleep after the Start.

Upvotes: 1

Related Questions