| File: SourceGeneration\GeneratorTimerExtensions.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Text; using Roslyn.Utilities; using static Microsoft.CodeAnalysis.CodeAnalysisEventSource; namespace Microsoft.CodeAnalysis { internal static class GeneratorTimerExtensions { public static RunTimer CreateGeneratorDriverRunTimer(this CodeAnalysisEventSource eventSource) { if (eventSource.IsEnabled(EventLevel.Informational, Keywords.Performance)) { var id = Guid.NewGuid().ToString(); eventSource.StartGeneratorDriverRunTime(id); return new RunTimer(t => eventSource.StopGeneratorDriverRunTime(t.Ticks, id)); } else { return new RunTimer(); } } public static RunTimer CreateSingleGeneratorRunTimer(this CodeAnalysisEventSource eventSource, ISourceGenerator generator, Func<TimeSpan, TimeSpan> adjustRunTime) { if (eventSource.IsEnabled(EventLevel.Informational, Keywords.Performance)) { var id = Guid.NewGuid().ToString(); var type = generator.GetGeneratorType(); eventSource.StartSingleGeneratorRunTime(type.FullName!, type.Assembly.Location, id); return new RunTimer(t => eventSource.StopSingleGeneratorRunTime(type.FullName!, type.Assembly.Location, t.Ticks, id), adjustRunTime); } else { return new RunTimer(adjustRunTime); } } internal readonly struct RunTimer : IDisposable { private readonly SharedStopwatch _timer; private readonly Action<TimeSpan>? _callback; private readonly Func<TimeSpan, TimeSpan>? _adjustRunTime; public TimeSpan Elapsed => _adjustRunTime is not null ? _adjustRunTime(_timer.Elapsed) : _timer.Elapsed; public RunTimer() { _timer = SharedStopwatch.StartNew(); _callback = null; _adjustRunTime = null; } public RunTimer(Func<TimeSpan, TimeSpan>? adjustRunTime) : this() { _adjustRunTime = adjustRunTime; } public RunTimer(Action<TimeSpan> callback, Func<TimeSpan, TimeSpan>? adjustRunTime = null) : this(adjustRunTime) { _callback = callback; } public void Dispose() { if (_callback is not null) { _callback(Elapsed); } } } } }