Skip to content

Commit f41b65f

Browse files
authored
Clean up Stopwatch a bit (#111834)
* Clean up Stopwatch a bit - Remove unnecessary Reset call from ctor - Remove unnecessary branch for _elapsed < 0 - Remove some defunct comments - Clean up style of Stop to match that of Start * More stylistic cleanup - Use expression-bodied properties - Remove unnecessary Debug.Asserts - Remove private method whose impl could just have been that of an existing public property - Change a private GetXx method to an Xx property. - Remove some type names that could be inferred
1 parent 843f798 commit f41b65f

File tree

1 file changed

+22
-69
lines changed
  • src/libraries/System.Private.CoreLib/src/System/Diagnostics

1 file changed

+22
-69
lines changed

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs

Lines changed: 22 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,22 @@
33

44
namespace System.Diagnostics
55
{
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-
106
[DebuggerDisplay("{DebuggerDisplay,nq}")]
117
public partial class Stopwatch
128
{
139
private long _elapsed;
1410
private long _startTimeStamp;
1511
private bool _isRunning;
1612

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.
2113
public static readonly long Frequency = QueryPerformanceFrequency();
2214
public static readonly bool IsHighResolution = true;
2315

2416
// 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.
2718
private static readonly double s_tickFrequency = (double)TimeSpan.TicksPerSecond / Frequency;
2819

2920
public Stopwatch()
3021
{
31-
Reset();
3222
}
3323

3424
public void Start()
@@ -43,7 +33,7 @@ public void Start()
4333

4434
public static Stopwatch StartNew()
4535
{
46-
Stopwatch s = new Stopwatch();
36+
Stopwatch s = new();
4737
s.Start();
4838
return s;
4939
}
@@ -53,29 +43,16 @@ public void Stop()
5343
// Calling stop on a stopped Stopwatch is a no-op.
5444
if (_isRunning)
5545
{
56-
long endTimeStamp = GetTimestamp();
57-
long elapsedThisPeriod = endTimeStamp - _startTimeStamp;
58-
_elapsed += elapsedThisPeriod;
46+
_elapsed += GetTimestamp() - _startTimeStamp;
5947
_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-
}
7148
}
7249
}
7350

7451
public void Reset()
7552
{
7653
_elapsed = 0;
77-
_isRunning = false;
7854
_startTimeStamp = 0;
55+
_isRunning = false;
7956
}
8057

8158
// Convenience method for replacing {sw.Reset(); sw.Start();} with a single sw.Restart()
@@ -94,32 +71,30 @@ public void Restart()
9471
/// </returns>
9572
public override string ToString() => Elapsed.ToString();
9673

97-
public bool IsRunning
98-
{
99-
get { return _isRunning; }
100-
}
74+
public bool IsRunning => _isRunning;
10175

102-
public TimeSpan Elapsed
103-
{
104-
get { return new TimeSpan(GetElapsedDateTimeTicks()); }
105-
}
76+
public TimeSpan Elapsed => new(ElapsedTimeSpanTicks);
10677

107-
public long ElapsedMilliseconds
108-
{
109-
get { return GetElapsedDateTimeTicks() / TimeSpan.TicksPerMillisecond; }
110-
}
78+
public long ElapsedMilliseconds => ElapsedTimeSpanTicks / TimeSpan.TicksPerMillisecond;
11179

11280
public long ElapsedTicks
11381
{
114-
get { return GetRawElapsedTicks(); }
115-
}
82+
get
83+
{
84+
long timeElapsed = _elapsed;
11685

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+
}
12194
}
12295

96+
public static long GetTimestamp() => QueryPerformanceCounter();
97+
12398
/// <summary>Gets the elapsed time since the <paramref name="startingTimestamp"/> value retrieved using <see cref="GetTimestamp"/>.</summary>
12499
/// <param name="startingTimestamp">The timestamp marking the beginning of the time period.</param>
125100
/// <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) =>
131106
/// <param name="endingTimestamp">The timestamp marking the end of the time period.</param>
132107
/// <returns>A <see cref="TimeSpan"/> for the elapsed time between the starting and ending timestamps.</returns>
133108
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));
140110

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);
159112

160113
private string DebuggerDisplay => $"{Elapsed} (IsRunning = {_isRunning})";
161114
}

0 commit comments

Comments
 (0)