From: Mikel Blanchard Date: Wed, 5 Aug 2020 20:45:22 +0000 (-0700) Subject: System.Diagnostics.Activity Perf Improvement (#40362) X-Git-Tag: submit/tizen/20210909.063632~6202 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b62f48287f9883d5af1f1384f2b9a007066439c5;p=platform%2Fupstream%2Fdotnet%2Fruntime.git System.Diagnostics.Activity Perf Improvement (#40362) --- diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index b5cd641..2383495 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -3,8 +3,10 @@ using System.Buffers.Binary; using System.Buffers.Text; +using System.Collections; using System.Collections.Generic; using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -33,6 +35,7 @@ namespace System.Diagnostics { #pragma warning disable CA1825 // Array.Empty() doesn't exist in all configurations private static readonly IEnumerable> s_emptyBaggageTags = new KeyValuePair[0]; + private static readonly IEnumerable> s_emptyTagObjects = new KeyValuePair[0]; private static readonly IEnumerable s_emptyLinks = new ActivityLink[0]; private static readonly IEnumerable s_emptyEvents = new ActivityEvent[0]; #pragma warning restore CA1825 @@ -255,7 +258,7 @@ namespace System.Diagnostics #if ALLOW_PARTIALLY_TRUSTED_CALLERS [System.Security.SecuritySafeCriticalAttribute] #endif - get => _tags?.Enumerate() ?? Unsafe.As>>(s_emptyBaggageTags); + get => _tags ?? s_emptyTagObjects; } /// @@ -264,7 +267,7 @@ namespace System.Diagnostics /// public IEnumerable Events { - get => _events != null ? _events.Enumerate() : s_emptyEvents; + get => _events ?? s_emptyEvents; } /// @@ -273,7 +276,7 @@ namespace System.Diagnostics /// public IEnumerable Links { - get => _links != null ? _links.Enumerate() : s_emptyLinks; + get => _links ?? s_emptyLinks; } /// @@ -1238,7 +1241,7 @@ namespace System.Diagnostics } // We are not using the public LinkedList because we need to ensure thread safety operation on the list. - private class LinkedList + private class LinkedList : IEnumerable { private LinkedListNode _first; private LinkedListNode _last; @@ -1269,18 +1272,12 @@ namespace System.Diagnostics } } - public IEnumerable Enumerate() - { - LinkedListNode? current = _first; - do - { - yield return current.Value; - current = current.Next; - } while (current != null); - } + public Enumerator GetEnumerator() => new Enumerator(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_first); } - private class TagsLinkedList + private class TagsLinkedList : IEnumerable> { private LinkedListNode>? _first; private LinkedListNode>? _last; @@ -1382,6 +1379,10 @@ namespace System.Diagnostics } } + public Enumerator> GetEnumerator() => new Enumerator>(_first); + IEnumerator> IEnumerable>.GetEnumerator() => new Enumerator>(_first); + IEnumerator IEnumerable.GetEnumerator() => new Enumerator>(_first); + public IEnumerable> EnumerateStringValues() { LinkedListNode>? current = _first; @@ -1390,22 +1391,47 @@ namespace System.Diagnostics { if (current.Value.Value is string || current.Value.Value == null) { - yield return new KeyValuePair(current.Value.Key, (string?) current.Value.Value); + yield return new KeyValuePair(current.Value.Key, (string?)current.Value.Value); } current = current.Next; }; } + } - public IEnumerable> Enumerate() + private struct Enumerator : IEnumerator + { + private readonly LinkedListNode? _head; + private LinkedListNode? _nextNode; + [AllowNull, MaybeNull] private T _currentItem; + + public Enumerator(LinkedListNode? head) { - LinkedListNode>? current = _first; + _nextNode = _head = head; + _currentItem = default; + } - while (current != null) + public T Current => _currentItem!; + + object? IEnumerator.Current => Current; + + public bool MoveNext() + { + if (_nextNode == null) { - yield return current.Value; - current = current.Next; - }; + _currentItem = default; + return false; + } + + _currentItem = _nextNode.Value; + _nextNode = _nextNode.Next; + return true; + } + + public void Reset() => _nextNode = _head; + + public void Dispose() + { } }