From 1acf021abd6c1a990ebf5c6e0702caecda0680b5 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Wed, 24 Jan 2024 11:21:36 +0300 Subject: [PATCH] Add benchmarks (#94) --- src/Benchmarks/AttributedBenchmarks.cs | 177 +++++++++++++++++- src/Benchmarks/Program.cs | 2 - .../Destructurama.Attributed.csproj | 1 + 3 files changed, 175 insertions(+), 5 deletions(-) diff --git a/src/Benchmarks/AttributedBenchmarks.cs b/src/Benchmarks/AttributedBenchmarks.cs index 5872bfa..2bb50bc 100644 --- a/src/Benchmarks/AttributedBenchmarks.cs +++ b/src/Benchmarks/AttributedBenchmarks.cs @@ -13,19 +13,190 @@ // limitations under the License. using BenchmarkDotNet.Attributes; +using Destructurama; +using Destructurama.Attributed; +using Serilog; +using Serilog.Core; namespace Benchmarks; public class AttributedBenchmarks { + private class LogAsScalarClass + { + [LogAsScalar] + public string? Name { get; set; } + + [LogAsScalar] + public LogAsScalarClass? Inner { get; set; } + + [LogAsScalar(isMutable: true)] + public LogAsScalarClass? Inner2 { get; set; } + } + + private class LogMaskedClass + { + [LogMasked] + public string? Password1 { get; set; } + + [LogMasked(ShowFirst = 3)] + public string? Password2 { get; set; } + + [LogMasked(ShowLast = 3)] + public string? Password3 { get; set; } + + [LogMasked(ShowFirst = 3, ShowLast = 3)] + public string? Password4 { get; set; } + } + + private class LogReplacedClass + { + private const string REGEX_WITH_VERTICAL_BARS = @"([a-zA-Z0-9]+)\|([a-zA-Z0-9]+)\|([a-zA-Z0-9]+)"; + + /// + /// 123|456|789 results in "***|456|789" + /// + [LogReplaced(REGEX_WITH_VERTICAL_BARS, "***|$2|$3")] + public string? RegexReplaceFirst { get; set; } + } + + private class LogWithNameClass + { + [LogWithName("OtherName1")] + public string? Name { get; set; } + + [LogWithName("OtherName2")] + public LogWithNameClass? Inner { get; set; } + } + + private class NotLoggedClass + { + [NotLogged] + public string? Name { get; set; } + + [NotLogged] + public NotLoggedClass? Inner { get; set; } + } + + private class NotLoggedIfDefaultClass + { + [NotLoggedIfDefault] + public string? Name { get; set; } + + [NotLoggedIfDefault] + public int Age { get; set; } + } + + private class NotLoggedIfNullClass + { + [NotLoggedIfNull] + public string? Name { get; set; } + + [NotLoggedIfNull] + public int Age { get; set; } + } + + private readonly LogAsScalarClass _logAsScalar = new() + { + Name = "Tom", + Inner = new LogAsScalarClass(), + Inner2 = new LogAsScalarClass(), + }; + + private readonly LogMaskedClass _logMasked = new() + { + Password1 = "abcdef123456", + Password2 = "abcdef123456", + Password3 = "abcdef123456", + Password4 = "abcdef123456", + }; + + private readonly LogReplacedClass _logReplaced = new() + { + RegexReplaceFirst = "123|456|789", + }; + + private readonly LogWithNameClass _logWithName = new() + { + Name = "Tome", + Inner = new LogWithNameClass(), + }; + + private readonly NotLoggedClass _notLogged = new() + { + Name = "Tom", + Inner = new NotLoggedClass(), + }; + + private readonly NotLoggedIfDefaultClass _notLoggedIfDefault = new() + { + }; + + private readonly NotLoggedIfNullClass _notLoggedIfNull = new() + { + }; + + private ILogEventPropertyValueFactory _factory = null!; + private IDestructuringPolicy _policy = null!; + [GlobalSetup] public void Setup() { + (_policy, _factory) = Build(c => c.Destructure.UsingAttributes()); + } + + private static (IDestructuringPolicy, ILogEventPropertyValueFactory) Build(Func configure) + { + var configuration = new LoggerConfiguration(); + var logger = configure(configuration).CreateLogger(); + + var processor = logger.GetType().GetField("_messageTemplateProcessor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!.GetValue(logger)!; + var converter = processor.GetType().GetField("_propertyValueConverter", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!.GetValue(processor)!; + var factory = (ILogEventPropertyValueFactory)converter; + var policies = (IDestructuringPolicy[])converter.GetType().GetField("_destructuringPolicies", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!.GetValue(converter)!; + var policy = policies.First(p => p is AttributedDestructuringPolicy); + return (policy, factory); + } + + [Benchmark] + public void LogAsScalar() + { + _policy.TryDestructure(_logAsScalar, _factory, out _); + } + + [Benchmark] + public void LogMasked() + { + _policy.TryDestructure(_logMasked, _factory, out _); + } + + [Benchmark] + public void LogReplaced() + { + _policy.TryDestructure(_logReplaced, _factory, out _); + } + + [Benchmark] + public void LogWithName() + { + _policy.TryDestructure(_logWithName, _factory, out _); + } + + [Benchmark] + public void NotLogged() + { + _policy.TryDestructure(_notLogged, _factory, out _); + } + + [Benchmark] + public void NotLoggedIfDefault() + { + _policy.TryDestructure(_notLoggedIfDefault, _factory, out _); } - //[Benchmark] - public void Execute() + [Benchmark] + public void NotLoggedIfNull() { - //TODO: implement + _policy.TryDestructure(_notLoggedIfNull, _factory, out _); } } diff --git a/src/Benchmarks/Program.cs b/src/Benchmarks/Program.cs index f66753c..bf3b7aa 100644 --- a/src/Benchmarks/Program.cs +++ b/src/Benchmarks/Program.cs @@ -15,9 +15,7 @@ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Running; -using Benchmarks; -new AttributedBenchmarks().Setup(); var config = ManualConfig .Create(DefaultConfig.Instance) .AddDiagnoser(MemoryDiagnoser.Default); diff --git a/src/Destructurama.Attributed/Destructurama.Attributed.csproj b/src/Destructurama.Attributed/Destructurama.Attributed.csproj index 67453a2..a3ded2d 100644 --- a/src/Destructurama.Attributed/Destructurama.Attributed.csproj +++ b/src/Destructurama.Attributed/Destructurama.Attributed.csproj @@ -11,6 +11,7 @@ +