From 2e5bec9a9cb305a05a825fadae5a6c8bd10b2bfc Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sat, 18 Feb 2023 12:13:58 +0300 Subject: [PATCH] Eliminates boxing of Dictionary.Enumerator for the most common use case --- .../Extensions/Logging/SerilogLoggerScope.cs | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs b/src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs index dd0803c..deb8ace 100644 --- a/src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs +++ b/src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs @@ -30,7 +30,7 @@ public SerilogLoggerScope(SerilogLoggerProvider provider, object state, IDisposa } public SerilogLoggerScope Parent { get; } - + public void Dispose() { if (!_disposed) @@ -51,42 +51,57 @@ public void Dispose() public void EnrichAndCreateScopeItem(LogEvent logEvent, ILogEventPropertyFactory propertyFactory, out LogEventPropertyValue scopeItem) { + void AddProperty(KeyValuePair stateProperty) + { + var key = stateProperty.Key; + var destructureObject = false; + var value = stateProperty.Value; + + if (key.StartsWith("@")) + { + key = key.Substring(1); + destructureObject = true; + } + + if (key.StartsWith("$")) + { + key = key.Substring(1); + value = value?.ToString(); + } + + var property = propertyFactory.CreateProperty(key, value, destructureObject); + logEvent.AddPropertyIfAbsent(property); + } + if (_state == null) { scopeItem = null; return; } - if (_state is IEnumerable> stateProperties) + // Eliminates boxing of Dictionary.Enumerator for the most common use case + if (_state is Dictionary dictionary) + { + scopeItem = null; // Unless it's `FormattedLogValues`, these are treated as property bags rather than scope items. + + foreach (var stateProperty in dictionary) + { + if (stateProperty.Key == SerilogLoggerProvider.OriginalFormatPropertyName && stateProperty.Value is string) + scopeItem = new ScalarValue(_state.ToString()); + else + AddProperty(stateProperty); + } + } + else if (_state is IEnumerable> stateProperties) { scopeItem = null; // Unless it's `FormattedLogValues`, these are treated as property bags rather than scope items. foreach (var stateProperty in stateProperties) { if (stateProperty.Key == SerilogLoggerProvider.OriginalFormatPropertyName && stateProperty.Value is string) - { scopeItem = new ScalarValue(_state.ToString()); - continue; - } - - var key = stateProperty.Key; - var destructureObject = false; - var value = stateProperty.Value; - - if (key.StartsWith("@")) - { - key = key.Substring(1); - destructureObject = true; - } - - if (key.StartsWith("$")) - { - key = key.Substring(1); - value = value?.ToString(); - } - - var property = propertyFactory.CreateProperty(key, value, destructureObject); - logEvent.AddPropertyIfAbsent(property); + else + AddProperty(stateProperty); } } else