3
3
4
4
namespace System . Diagnostics
5
5
{
6
- // This class uses high-resolution performance counter if the installed
7
- // hardware supports it. Otherwise, the class will fall back to DateTime
8
- // and uses ticks as a measurement.
9
-
10
6
[ DebuggerDisplay ( "{DebuggerDisplay,nq}" ) ]
11
7
public partial class Stopwatch
12
8
{
13
9
private long _elapsed ;
14
10
private long _startTimeStamp ;
15
11
private bool _isRunning ;
16
12
17
- // "Frequency" stores the frequency of the high-resolution performance counter,
18
- // if one exists. Otherwise it will store TicksPerSecond.
19
- // The frequency cannot change while the system is running,
20
- // so we only need to initialize it once.
21
13
public static readonly long Frequency = QueryPerformanceFrequency ( ) ;
22
14
public static readonly bool IsHighResolution = true ;
23
15
24
16
// performance-counter frequency, in counts per ticks.
25
- // This can speed up conversion from high frequency performance-counter
26
- // to ticks.
17
+ // This can speed up conversion to ticks.
27
18
private static readonly double s_tickFrequency = ( double ) TimeSpan . TicksPerSecond / Frequency ;
28
19
29
20
public Stopwatch ( )
30
21
{
31
- Reset ( ) ;
32
22
}
33
23
34
24
public void Start ( )
@@ -43,7 +33,7 @@ public void Start()
43
33
44
34
public static Stopwatch StartNew ( )
45
35
{
46
- Stopwatch s = new Stopwatch ( ) ;
36
+ Stopwatch s = new ( ) ;
47
37
s . Start ( ) ;
48
38
return s ;
49
39
}
@@ -53,29 +43,16 @@ public void Stop()
53
43
// Calling stop on a stopped Stopwatch is a no-op.
54
44
if ( _isRunning )
55
45
{
56
- long endTimeStamp = GetTimestamp ( ) ;
57
- long elapsedThisPeriod = endTimeStamp - _startTimeStamp ;
58
- _elapsed += elapsedThisPeriod ;
46
+ _elapsed += GetTimestamp ( ) - _startTimeStamp ;
59
47
_isRunning = false ;
60
-
61
- if ( _elapsed < 0 )
62
- {
63
- // When measuring small time periods the Stopwatch.Elapsed*
64
- // properties can return negative values. This is due to
65
- // bugs in the basic input/output system (BIOS) or the hardware
66
- // abstraction layer (HAL) on machines with variable-speed CPUs
67
- // (e.g. Intel SpeedStep).
68
-
69
- _elapsed = 0 ;
70
- }
71
48
}
72
49
}
73
50
74
51
public void Reset ( )
75
52
{
76
53
_elapsed = 0 ;
77
- _isRunning = false ;
78
54
_startTimeStamp = 0 ;
55
+ _isRunning = false ;
79
56
}
80
57
81
58
// Convenience method for replacing {sw.Reset(); sw.Start();} with a single sw.Restart()
@@ -94,32 +71,30 @@ public void Restart()
94
71
/// </returns>
95
72
public override string ToString ( ) => Elapsed . ToString ( ) ;
96
73
97
- public bool IsRunning
98
- {
99
- get { return _isRunning ; }
100
- }
74
+ public bool IsRunning => _isRunning ;
101
75
102
- public TimeSpan Elapsed
103
- {
104
- get { return new TimeSpan ( GetElapsedDateTimeTicks ( ) ) ; }
105
- }
76
+ public TimeSpan Elapsed => new ( ElapsedTimeSpanTicks ) ;
106
77
107
- public long ElapsedMilliseconds
108
- {
109
- get { return GetElapsedDateTimeTicks ( ) / TimeSpan . TicksPerMillisecond ; }
110
- }
78
+ public long ElapsedMilliseconds => ElapsedTimeSpanTicks / TimeSpan . TicksPerMillisecond ;
111
79
112
80
public long ElapsedTicks
113
81
{
114
- get { return GetRawElapsedTicks ( ) ; }
115
- }
82
+ get
83
+ {
84
+ long timeElapsed = _elapsed ;
116
85
117
- public static long GetTimestamp ( )
118
- {
119
- Debug . Assert ( IsHighResolution ) ;
120
- return QueryPerformanceCounter ( ) ;
86
+ // If the Stopwatch is running, add elapsed time since the Stopwatch is started last time.
87
+ if ( _isRunning )
88
+ {
89
+ timeElapsed += GetTimestamp ( ) - _startTimeStamp ;
90
+ }
91
+
92
+ return timeElapsed ;
93
+ }
121
94
}
122
95
96
+ public static long GetTimestamp ( ) => QueryPerformanceCounter ( ) ;
97
+
123
98
/// <summary>Gets the elapsed time since the <paramref name="startingTimestamp"/> value retrieved using <see cref="GetTimestamp"/>.</summary>
124
99
/// <param name="startingTimestamp">The timestamp marking the beginning of the time period.</param>
125
100
/// <returns>A <see cref="TimeSpan"/> for the elapsed time between the starting timestamp and the time of this call.</returns>
@@ -131,31 +106,9 @@ public static TimeSpan GetElapsedTime(long startingTimestamp) =>
131
106
/// <param name="endingTimestamp">The timestamp marking the end of the time period.</param>
132
107
/// <returns>A <see cref="TimeSpan"/> for the elapsed time between the starting and ending timestamps.</returns>
133
108
public static TimeSpan GetElapsedTime ( long startingTimestamp , long endingTimestamp ) =>
134
- new TimeSpan ( ( long ) ( ( endingTimestamp - startingTimestamp ) * s_tickFrequency ) ) ;
135
-
136
- // Get the elapsed ticks.
137
- private long GetRawElapsedTicks ( )
138
- {
139
- long timeElapsed = _elapsed ;
109
+ new ( ( long ) ( ( endingTimestamp - startingTimestamp ) * s_tickFrequency ) ) ;
140
110
141
- if ( _isRunning )
142
- {
143
- // If the Stopwatch is running, add elapsed time since
144
- // the Stopwatch is started last time.
145
- long currentTimeStamp = GetTimestamp ( ) ;
146
- long elapsedUntilNow = currentTimeStamp - _startTimeStamp ;
147
- timeElapsed += elapsedUntilNow ;
148
- }
149
- return timeElapsed ;
150
- }
151
-
152
- // Get the elapsed ticks.
153
- private long GetElapsedDateTimeTicks ( )
154
- {
155
- Debug . Assert ( IsHighResolution ) ;
156
- // convert high resolution perf counter to DateTime ticks
157
- return unchecked ( ( long ) ( GetRawElapsedTicks ( ) * s_tickFrequency ) ) ;
158
- }
111
+ private long ElapsedTimeSpanTicks => ( long ) ( ElapsedTicks * s_tickFrequency ) ;
159
112
160
113
private string DebuggerDisplay => $ "{ Elapsed } (IsRunning = { _isRunning } )";
161
114
}
0 commit comments