diff --git a/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs b/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs index ecb9a1d0095f951b336c1091b514cb72b0d5ee7d..13ef199900b3b3fb26836f2a428cbc017442f5d9 100644 --- a/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs +++ b/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs @@ -51,7 +51,7 @@ public async Task RunAsync(Workspace workspace, CancellationToken cancellationTo } var solution = workspace.CurrentSolution; - var stopwatch = Stopwatch.StartNew(); + var stopwatch = PerformanceTracker.StartNew(); var updatedSolution = solution; diff --git a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs index 49d0271ca0d0a11db03797eed8528978d2632b4a..13edd8b1a90f1819261b8febda865b04242aabf8 100644 --- a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs +++ b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs @@ -45,12 +45,12 @@ public async Task RunAsync(Workspace workspace, CancellationToken cancellationTo } var solution = workspace.CurrentSolution; - var stopwatch = Stopwatch.StartNew(); + var stopwatch = PerformanceTracker.StartNew(); var analysisResult = await GetAnalysisResultAsync(solution, _analyzers, _options, cancellationToken).ConfigureAwait(false); var allDiagnostics = analysisResult.Where(pair => pair.Value != null).SelectMany(pair => pair.Value.GetAllDiagnostics()).ToImmutableArray(); - Console.WriteLine($"Found {allDiagnostics.Length} diagnostics in {stopwatch.ElapsedMilliseconds}ms"); + Console.WriteLine($"Found {allDiagnostics.Length} diagnostics in {stopwatch.GetSummary(preciseMemory: true)}"); WriteTelemetry(analysisResult); if (_options.TestDocuments) diff --git a/src/Tools/AnalyzerRunner/PerformanceTracker.cs b/src/Tools/AnalyzerRunner/PerformanceTracker.cs new file mode 100644 index 0000000000000000000000000000000000000000..40bd37fccccaecd67c3d5d983cabd62c817aeefc --- /dev/null +++ b/src/Tools/AnalyzerRunner/PerformanceTracker.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; + +namespace AnalyzerRunner +{ + internal sealed class PerformanceTracker + { + private readonly Stopwatch _stopwatch; +#if NETCOREAPP + private readonly long _initialTotalAllocatedBytes; +#endif + + public PerformanceTracker(Stopwatch stopwatch, long initialTotalAllocatedBytes) + { +#if NETCOREAPP + _initialTotalAllocatedBytes = initialTotalAllocatedBytes; +#endif + _stopwatch = stopwatch; + } + + public static PerformanceTracker StartNew(bool preciseMemory = true) + { +#if NETCOREAPP + var initialTotalAllocatedBytes = GC.GetTotalAllocatedBytes(preciseMemory); +#else + var initialTotalAllocatedBytes = 0L; +#endif + + return new PerformanceTracker(Stopwatch.StartNew(), initialTotalAllocatedBytes); + } + + public TimeSpan Elapsed => _stopwatch.Elapsed; + + public string GetSummary(bool preciseMemory = true) + { +#if NETCOREAPP + var elapsedTime = Elapsed; + var allocatedBytes = GC.GetTotalAllocatedBytes(preciseMemory) - _initialTotalAllocatedBytes; + + return $"{elapsedTime.TotalMilliseconds:0}ms ({allocatedBytes} bytes allocated)"; +#else + return $"{Elapsed.TotalMilliseconds:0}ms"; +#endif + } + } +} diff --git a/src/Tools/AnalyzerRunner/Program.cs b/src/Tools/AnalyzerRunner/Program.cs index e9d62d508d9f5e3218320e4cd6e7f1b2989906e5..2481bc4ed0aa1fbaecbb05d5ebcb47c9761a59d5 100644 --- a/src/Tools/AnalyzerRunner/Program.cs +++ b/src/Tools/AnalyzerRunner/Program.cs @@ -77,7 +77,7 @@ public static async Task Main(string[] args) ProfileOptimization.SetProfileRoot(options.ProfileRoot); } - Stopwatch stopwatch = Stopwatch.StartNew(); + var stopwatch = PerformanceTracker.StartNew(); var properties = new Dictionary { #if NETCOREAPP @@ -105,10 +105,12 @@ public static async Task Main(string[] args) solution = solution.WithProjectAnalyzerReferences(projectId, ImmutableArray.Empty); } - Console.WriteLine($"Loaded solution in {stopwatch.ElapsedMilliseconds}ms"); + Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); if (options.ShowStats) { + stopwatch = PerformanceTracker.StartNew(); + List projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); Console.WriteLine("Number of projects:\t\t" + projects.Count); @@ -119,6 +121,8 @@ public static async Task Main(string[] args) Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); Console.WriteLine("Number of syntax trivia:\t" + statistics.NumberOfTrivia); + + Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); } if (options.ShowCompilerDiagnostics)