Skip to content

Commit

Permalink
System.Diagnostics.Activity Perf Improvement (#40362)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch authored Aug 5, 2020
1 parent fe41d3c commit b62f482
Showing 1 changed file with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -33,6 +35,7 @@ public partial class Activity : IDisposable
{
#pragma warning disable CA1825 // Array.Empty<T>() doesn't exist in all configurations
private static readonly IEnumerable<KeyValuePair<string, string?>> s_emptyBaggageTags = new KeyValuePair<string, string?>[0];
private static readonly IEnumerable<KeyValuePair<string, object?>> s_emptyTagObjects = new KeyValuePair<string, object?>[0];
private static readonly IEnumerable<ActivityLink> s_emptyLinks = new ActivityLink[0];
private static readonly IEnumerable<ActivityEvent> s_emptyEvents = new ActivityEvent[0];
#pragma warning restore CA1825
Expand Down Expand Up @@ -255,7 +258,7 @@ public string? RootId
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
get => _tags?.Enumerate() ?? Unsafe.As<IEnumerable<KeyValuePair<string, object?>>>(s_emptyBaggageTags);
get => _tags ?? s_emptyTagObjects;
}

/// <summary>
Expand All @@ -264,7 +267,7 @@ public string? RootId
/// </summary>
public IEnumerable<ActivityEvent> Events
{
get => _events != null ? _events.Enumerate() : s_emptyEvents;
get => _events ?? s_emptyEvents;
}

/// <summary>
Expand All @@ -273,7 +276,7 @@ public IEnumerable<ActivityEvent> Events
/// </summary>
public IEnumerable<ActivityLink> Links
{
get => _links != null ? _links.Enumerate() : s_emptyLinks;
get => _links ?? s_emptyLinks;
}

/// <summary>
Expand Down Expand Up @@ -1238,7 +1241,7 @@ private partial class LinkedListNode<T>
}

// We are not using the public LinkedList<T> because we need to ensure thread safety operation on the list.
private class LinkedList<T>
private class LinkedList<T> : IEnumerable<T>
{
private LinkedListNode<T> _first;
private LinkedListNode<T> _last;
Expand Down Expand Up @@ -1269,18 +1272,12 @@ public void Add(T value)
}
}

public IEnumerable<T> Enumerate()
{
LinkedListNode<T>? current = _first;
do
{
yield return current.Value;
current = current.Next;
} while (current != null);
}
public Enumerator<T> GetEnumerator() => new Enumerator<T>(_first);
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator<T>(_first);
IEnumerator IEnumerable.GetEnumerator() => new Enumerator<T>(_first);
}

private class TagsLinkedList
private class TagsLinkedList : IEnumerable<KeyValuePair<string, object?>>
{
private LinkedListNode<KeyValuePair<string, object?>>? _first;
private LinkedListNode<KeyValuePair<string, object?>>? _last;
Expand Down Expand Up @@ -1382,6 +1379,10 @@ public void Set(KeyValuePair<string, object?> value)
}
}

public Enumerator<KeyValuePair<string, object?>> GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);
IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);
IEnumerator IEnumerable.GetEnumerator() => new Enumerator<KeyValuePair<string, object?>>(_first);

public IEnumerable<KeyValuePair<string, string?>> EnumerateStringValues()
{
LinkedListNode<KeyValuePair<string, object?>>? current = _first;
Expand All @@ -1390,22 +1391,47 @@ public void Set(KeyValuePair<string, object?> value)
{
if (current.Value.Value is string || current.Value.Value == null)
{
yield return new KeyValuePair<string, string?>(current.Value.Key, (string?) current.Value.Value);
yield return new KeyValuePair<string, string?>(current.Value.Key, (string?)current.Value.Value);
}

current = current.Next;
};
}
}

public IEnumerable<KeyValuePair<string, object?>> Enumerate()
private struct Enumerator<T> : IEnumerator<T>
{
private readonly LinkedListNode<T>? _head;
private LinkedListNode<T>? _nextNode;
[AllowNull, MaybeNull] private T _currentItem;

public Enumerator(LinkedListNode<T>? head)
{
LinkedListNode<KeyValuePair<string, object?>>? 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()
{
}
}

Expand Down

0 comments on commit b62f482

Please sign in to comment.