Skip to content

Commit

Permalink
Minimize the new SharedStopwatch API
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Jan 27, 2020
1 parent 775c4eb commit ce6b1a9
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1453,17 +1453,17 @@ private void ExecuteAndCatchIfThrows_NoLock<TArg>(DiagnosticAnalyzer analyzer, A
{
timer = SharedStopwatch.StartNew();

// This call to Restart isn't required by the API, but is included to avoid measurement errors which
// can occur during periods of high allocation activity. In some cases, calls to Stopwatch
// This call to StartNew isn't required by the API, but is included to avoid measurement errors
// which can occur during periods of high allocation activity. In some cases, calls to Stopwatch
// operations can block at their return point on the completion of a background GC operation. When
// this occurs, the GC wait time ends up included in the measured time span. In the event the first
// call to Restart blocked on a GC operation, this call to Restart will most likely occur when the
// call to StartNew blocked on a GC operation, this call to StartNew will most likely occur when the
// GC is no longer active. In practice, a substantial improvement to the consistency of analyzer
// timing data was observed.
//
// Note that the call to Stopwatch.Stop() is not affected, because the GC wait will occur after the
// timer has already recorded its stop time.
timer.Restart();
// Note that the call to SharedStopwatch.Elapsed is not affected, because the GC wait will occur
// after the timer has already recorded its stop time.
timer = SharedStopwatch.StartNew();
}

analyze(argument);
Expand Down
53 changes: 6 additions & 47 deletions src/Compilers/Core/Portable/InternalUtilities/SharedStopwatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,20 @@

namespace Roslyn.Utilities
{
internal struct SharedStopwatch
internal readonly struct SharedStopwatch
{
private static readonly Stopwatch s_stopwatch = Stopwatch.StartNew();

private TimeSpan _accumulated;
private TimeSpan _started;
private readonly TimeSpan _started;

public readonly TimeSpan Elapsed
private SharedStopwatch(TimeSpan started)
{
get
{
if (IsRunning)
return _accumulated + s_stopwatch.Elapsed - _started;

return _accumulated;
}
_started = started;
}

public readonly long ElapsedMilliseconds => (long)Elapsed.TotalMilliseconds;
public readonly bool IsRunning => _started != TimeSpan.Zero;
public TimeSpan Elapsed => s_stopwatch.Elapsed - _started;

public static SharedStopwatch StartNew()
{
var result = new SharedStopwatch();
result.Start();
return result;
}

public void Reset()
{
Stop();
_accumulated = TimeSpan.Zero;
}

public void Restart()
{
Reset();
Start();
}

public void Start()
{
if (!IsRunning)
{
_started = s_stopwatch.Elapsed;
}
}

public void Stop()
{
if (IsRunning)
{
_accumulated += s_stopwatch.Elapsed - _started;
_started = TimeSpan.Zero;
}
}
=> new SharedStopwatch(s_stopwatch.Elapsed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<ItemGroup Label="Linked Files">
<Compile Remove="Storage\Sqlite\**\*.cs" Condition="'$(DotNetBuildFromSource)' == 'true'" />
<Compile Include="..\..\..\CodeStyle\Core\CodeFixes\FixAllContextHelper.cs" Link="CodeFixes\FixAllOccurrences\FixAllContextHelper.cs" />
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\SharedStopwatch.cs" Link="InternalUtilities\SharedStopwatch.cs" />
<Compile Include="..\..\..\Compilers\Shared\DesktopAnalyzerAssemblyLoader.cs">
<Link>Execution\Desktop\DesktopAnalyzerAssemblyLoader.cs</Link>
</Compile>
Expand Down

0 comments on commit ce6b1a9

Please sign in to comment.