From 94e104939eba231f6de937597d7847f5b2bad55e Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Tue, 19 Mar 2024 12:37:20 +0100 Subject: [PATCH] use custom interpolated string handler --- MareSynchronos/FileCache/CacheMonitor.cs | 2 +- .../PlayerData/Factories/PlayerDataFactory.cs | 2 +- .../PlayerData/Handlers/GameObjectHandler.cs | 4 +-- MareSynchronos/Services/DalamudUtilService.cs | 10 +++--- .../Mediator/WindowMediatorSubscriberBase.cs | 2 +- .../Services/PerformanceCollectorService.cs | 31 ++++++++++--------- .../Utils/MareInterpolatedStringHandler.cs | 27 ++++++++++++++++ 7 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 MareSynchronos/Utils/MareInterpolatedStringHandler.cs diff --git a/MareSynchronos/FileCache/CacheMonitor.cs b/MareSynchronos/FileCache/CacheMonitor.cs index 38947f6..3948cd7 100644 --- a/MareSynchronos/FileCache/CacheMonitor.cs +++ b/MareSynchronos/FileCache/CacheMonitor.cs @@ -368,7 +368,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase { try { - _performanceCollector.LogPerformance(this, "FullFileScan", () => FullFileScan(token)); + _performanceCollector.LogPerformance(this, $"FullFileScan", () => FullFileScan(token)); } catch (Exception ex) { diff --git a/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs b/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs index 82ed81b..5080e83 100644 --- a/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs +++ b/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs @@ -76,7 +76,7 @@ public class PlayerDataFactory try { - await _performanceCollector.LogPerformance(this, "CreateCharacterData>" + playerRelatedObject.ObjectKind, async () => + await _performanceCollector.LogPerformance(this, $"CreateCharacterData>{playerRelatedObject.ObjectKind}", async () => { await CreateCharacterData(previousData, playerRelatedObject, token).ConfigureAwait(false); }).ConfigureAwait(true); diff --git a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs index 8a3ed8b..1af8031 100644 --- a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs +++ b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs @@ -381,8 +381,8 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase try { - _performanceCollector.LogPerformance(this, "CheckAndUpdateObject>" + (_isOwnedObject ? "Self+" : "Other+") + ObjectKind + "/" - + (string.IsNullOrEmpty(Name) ? "Unk" : Name) + "+" + Address.ToString("X"), CheckAndUpdateObject); + _performanceCollector.LogPerformance(this, $"CheckAndUpdateObject>{(_isOwnedObject ? "Self" : "Other")}+{ObjectKind}/{(string.IsNullOrEmpty(Name) ? "Unk" : Name)}" + + $"+{Address.ToString("X")}", CheckAndUpdateObject); } catch (Exception ex) { diff --git a/MareSynchronos/Services/DalamudUtilService.cs b/MareSynchronos/Services/DalamudUtilService.cs index b9e1e86..8078bc6 100644 --- a/MareSynchronos/Services/DalamudUtilService.cs +++ b/MareSynchronos/Services/DalamudUtilService.cs @@ -270,7 +270,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0) { var fileName = Path.GetFileNameWithoutExtension(callerFilePath); - await _performanceCollector.LogPerformance(this, "RunOnFramework:Act/" + fileName + ">" + callerMember + ":" + callerLineNumber, async () => + await _performanceCollector.LogPerformance(this, $"RunOnFramework:Act/{fileName}>{callerMember}:{callerLineNumber}", async () => { if (!_framework.IsInFrameworkUpdateThread) { @@ -289,7 +289,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber public async Task RunOnFrameworkThread(Func func, [CallerMemberName] string callerMember = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0) { var fileName = Path.GetFileNameWithoutExtension(callerFilePath); - return await _performanceCollector.LogPerformance(this, "RunOnFramework:Func<" + typeof(T) + ">/" + fileName + ">" + callerMember + ":" + callerLineNumber, async () => + return await _performanceCollector.LogPerformance(this, $"RunOnFramework:Func<{typeof(T)}>/{fileName}>{callerMember}:{callerLineNumber}", async () => { if (!_framework.IsInFrameworkUpdateThread) { @@ -467,7 +467,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber private void FrameworkOnUpdate(IFramework framework) { - _performanceCollector.LogPerformance(this, "FrameworkOnUpdate", FrameworkOnUpdateInternal); + _performanceCollector.LogPerformance(this, $"FrameworkOnUpdate", FrameworkOnUpdateInternal); } private unsafe void FrameworkOnUpdateInternal() @@ -479,10 +479,10 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber bool isNormalFrameworkUpdate = DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1); - _performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal+" + (isNormalFrameworkUpdate ? "Regular" : "Delayed"), () => + _performanceCollector.LogPerformance(this, $"FrameworkOnUpdateInternal+{(isNormalFrameworkUpdate ? "Regular" : "Delayed")}", () => { IsAnythingDrawing = false; - _performanceCollector.LogPerformance(this, "ObjTableToCharas", + _performanceCollector.LogPerformance(this, $"ObjTableToCharas", () => { if (_sentBetweenAreas) diff --git a/MareSynchronos/Services/Mediator/WindowMediatorSubscriberBase.cs b/MareSynchronos/Services/Mediator/WindowMediatorSubscriberBase.cs index 87a7b41..5e905fd 100644 --- a/MareSynchronos/Services/Mediator/WindowMediatorSubscriberBase.cs +++ b/MareSynchronos/Services/Mediator/WindowMediatorSubscriberBase.cs @@ -35,7 +35,7 @@ public abstract class WindowMediatorSubscriberBase : Window, IMediatorSubscriber public override void Draw() { - _performanceCollectorService.LogPerformance(this, "Draw", DrawInternal); + _performanceCollectorService.LogPerformance(this, $"Draw", DrawInternal); } protected abstract void DrawInternal(); diff --git a/MareSynchronos/Services/PerformanceCollectorService.cs b/MareSynchronos/Services/PerformanceCollectorService.cs index 22a132d..fad205c 100644 --- a/MareSynchronos/Services/PerformanceCollectorService.cs +++ b/MareSynchronos/Services/PerformanceCollectorService.cs @@ -14,7 +14,7 @@ public sealed class PerformanceCollectorService : IHostedService private readonly ILogger _logger; private readonly MareConfigService _mareConfigService; public ConcurrentDictionary> PerformanceCounters { get; } = new(StringComparer.Ordinal); - private readonly CancellationTokenSource _periodicLogPruneTask = new(); + private readonly CancellationTokenSource _periodicLogPruneTaskCts = new(); public PerformanceCollectorService(ILogger logger, MareConfigService mareConfigService) { @@ -22,15 +22,15 @@ public sealed class PerformanceCollectorService : IHostedService _mareConfigService = mareConfigService; } - public T LogPerformance(object sender, string counterName, Func func, int maxEntries = 10000) + public T LogPerformance(object sender, MareInterpolatedStringHandler counterName, Func func, int maxEntries = 10000) { if (!_mareConfigService.Current.LogPerformance) return func.Invoke(); - counterName = sender.GetType().Name + _counterSplit + counterName; + string cn = sender.GetType().Name + _counterSplit + counterName.BuildMessage(); - if (!PerformanceCounters.TryGetValue(counterName, out var list)) + if (!PerformanceCounters.TryGetValue(cn, out var list)) { - list = PerformanceCounters[counterName] = new(maxEntries); + list = PerformanceCounters[cn] = new(maxEntries); } var dt = DateTime.UtcNow.Ticks; @@ -43,21 +43,21 @@ public sealed class PerformanceCollectorService : IHostedService var elapsed = DateTime.UtcNow.Ticks - dt; #if DEBUG if (TimeSpan.FromTicks(elapsed) > TimeSpan.FromMilliseconds(10)) - _logger.LogWarning(">10ms spike on {counterName}: {time}", counterName, TimeSpan.FromTicks(elapsed)); + _logger.LogWarning(">10ms spike on {counterName}: {time}", cn, TimeSpan.FromTicks(elapsed)); #endif list.Add((TimeOnly.FromDateTime(DateTime.Now), elapsed)); } } - public void LogPerformance(object sender, string counterName, Action act, int maxEntries = 10000) + public void LogPerformance(object sender, MareInterpolatedStringHandler counterName, Action act, int maxEntries = 10000) { if (!_mareConfigService.Current.LogPerformance) { act.Invoke(); return; } - counterName = sender.GetType().Name + _counterSplit + counterName; + var cn = sender.GetType().Name + _counterSplit + counterName.BuildMessage(); - if (!PerformanceCounters.TryGetValue(counterName, out var list)) + if (!PerformanceCounters.TryGetValue(cn, out var list)) { - list = PerformanceCounters[counterName] = new(maxEntries); + list = PerformanceCounters[cn] = new(maxEntries); } var dt = DateTime.UtcNow.Ticks; @@ -70,7 +70,7 @@ public sealed class PerformanceCollectorService : IHostedService var elapsed = DateTime.UtcNow.Ticks - dt; #if DEBUG if (TimeSpan.FromTicks(elapsed) > TimeSpan.FromMilliseconds(10)) - _logger.LogWarning(">10ms spike on {counterName}: {time}", counterName, TimeSpan.FromTicks(elapsed)); + _logger.LogWarning(">10ms spike on {counterName}: {time}", cn, TimeSpan.FromTicks(elapsed)); #endif list.Add(new(TimeOnly.FromDateTime(DateTime.Now), elapsed)); } @@ -79,14 +79,15 @@ public sealed class PerformanceCollectorService : IHostedService public Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Starting PerformanceCollectorService"); - _ = Task.Run(PeriodicLogPrune, _periodicLogPruneTask.Token); + _ = Task.Run(PeriodicLogPrune, _periodicLogPruneTaskCts.Token); _logger.LogInformation("Started PerformanceCollectorService"); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { - _periodicLogPruneTask.Cancel(); + _periodicLogPruneTaskCts.Cancel(); + _periodicLogPruneTaskCts.Dispose(); return Task.CompletedTask; } @@ -174,9 +175,9 @@ public sealed class PerformanceCollectorService : IHostedService private async Task PeriodicLogPrune() { - while (!_periodicLogPruneTask.Token.IsCancellationRequested) + while (!_periodicLogPruneTaskCts.Token.IsCancellationRequested) { - await Task.Delay(TimeSpan.FromMinutes(10), _periodicLogPruneTask.Token).ConfigureAwait(false); + await Task.Delay(TimeSpan.FromMinutes(10), _periodicLogPruneTaskCts.Token).ConfigureAwait(false); foreach (var entries in PerformanceCounters.ToList()) { diff --git a/MareSynchronos/Utils/MareInterpolatedStringHandler.cs b/MareSynchronos/Utils/MareInterpolatedStringHandler.cs new file mode 100644 index 0000000..2f96533 --- /dev/null +++ b/MareSynchronos/Utils/MareInterpolatedStringHandler.cs @@ -0,0 +1,27 @@ +using System.Runtime.CompilerServices; +using System.Text; + +namespace MareSynchronos.Utils; + +[InterpolatedStringHandler] +public readonly ref struct MareInterpolatedStringHandler +{ + readonly StringBuilder _logMessageStringbuilder; + + public MareInterpolatedStringHandler(int literalLength, int formattedCount) + { + _logMessageStringbuilder = new StringBuilder(literalLength); + } + + public void AppendLiteral(string s) + { + _logMessageStringbuilder.Append(s); + } + + public void AppendFormatted(T t) + { + _logMessageStringbuilder.Append(t?.ToString()); + } + + public string BuildMessage() => _logMessageStringbuilder.ToString(); +}