qamp/Qrakhen.Qamp.Core/Benchmark.cs

91 lines
2.4 KiB
C#

using Qrakhen.Qamp.Core.Logging;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Qrakhen.Qamp.Core;
public static class Benchmark
{
private static readonly Dictionary<string, Stopwatch> _clocks = new();
public static bool Active { get; set; }
private static readonly ILogger _logger = LoggerService.Get(nameof(Benchmark));
private static string MakeKey(string? id, string? member, string? file)
{
if (member == null)
return "global";
return $"{file?.Split('\\').Last() ?? "unknown"}{(id == null ? "" : $"<{id}>")}::{member}";
}
public static void Start(
string? message = null,
string? id = null,
[CallerMemberName] string? member = null,
[CallerFilePath] string? file = null,
[CallerLineNumber] int? line = null)
{
if (!Active)
return;
string key = MakeKey(id, member, file);
if (!_clocks.TryGetValue(key, out Stopwatch? sw)) {
sw = _clocks[key] = new Stopwatch();
Console.WriteLine($" ::: Registered new benchmark clock '{key}'");
}
if (!string.IsNullOrEmpty(message))
Console.WriteLine($" ::: {key}:{line} > {message}");
if (sw.IsRunning)
Console.WriteLine($" ::: {key}:{line} > already running with an elapsed time of {sw.Elapsed}. clock was reset.");
sw.Reset();
sw.Start();
}
public static long Report(
string? message = null,
string? id = null,
bool keep = true,
[CallerMemberName] string? member = null,
[CallerFilePath] string? file = null,
[CallerLineNumber] int? line = null)
{
if (!Active)
return 0;
string key = MakeKey(id, member, file);
if (!_clocks.TryGetValue(key, out Stopwatch sw)) {
#if LOG
_logger.Debug($"No clock found for '{key}', start one first using Benchmark.Start()");
#endif
return 0;
}
sw.Stop();
#if LOG
_logger.Debug($" ::: {key}:{line} > {message ?? "Elapsed"}: {sw.Elapsed}");
#endif
if (keep)
sw.Start();
return sw.ElapsedMilliseconds;
}
public static long End(
string? message = null,
string? id = null,
[CallerMemberName] string? member = null,
[CallerFilePath] string? file = null,
[CallerLineNumber] int? line = null)
{
if (!Active)
return 0;
return Report(message, id, false, member, file, line);
}
}