Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

Commit

Permalink
[Perf] Improve enumerators in internal custom collections (#1639)
Browse files Browse the repository at this point in the history
This makes it so there is no Enumerator created, as the compiler is smart
enough to detect that if there is a strongly typed GetEnumerator() method
with a return value that structurally matches IEnumerator, it'll prefer
that.
In this case, we're talking about structs. This will save us IEnumerator
allocations all over the place.
  • Loading branch information
Therzok committed Sep 26, 2016
1 parent 5f5d0b7 commit 5bb28f8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
Expand Up @@ -67,15 +67,20 @@ class CompletionResult : IReadOnlyList<CompletionData>

public readonly List<IMethodSymbol> PossibleDelegates = new List<IMethodSymbol>();

public List<CompletionData>.Enumerator GetEnumerator ()
{
return data.GetEnumerator ();
}

#region IReadOnlyList<ICompletionData> implemenation
public IEnumerator<CompletionData> GetEnumerator()
IEnumerator<CompletionData> IEnumerable<CompletionData>.GetEnumerator ()
{
return data.GetEnumerator();
return data.GetEnumerator ();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)data).GetEnumerator();
return data.GetEnumerator();
}

public CompletionData this[int index] {
Expand Down
Expand Up @@ -42,11 +42,16 @@ class ParameterHintingResult : IReadOnlyList<IParameterHintingData>
private set;
}

public List<IParameterHintingData>.Enumerator GetEnumerator ()
{
return data.GetEnumerator ();
}

#region IReadOnlyList<IParameterHintingData> implementation
public IEnumerator<IParameterHintingData> GetEnumerator()

IEnumerator<IParameterHintingData> IEnumerable<IParameterHintingData>.GetEnumerator ()
{
return data.GetEnumerator();
return data.GetEnumerator ();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
Expand Down
20 changes: 12 additions & 8 deletions main/src/addins/CSharpBinding/Util/CloneableStack.cs
Expand Up @@ -34,8 +34,12 @@ class CloneableStack<T> : IEnumerable<T>, ICollection<T>, ICloneable, IEquatable
int count;
StackItem top;

public StackItemEnumerator GetEnumerator ()
{
return new StackItemEnumerator (top);
}
#region IEnumerable[T] implementation
public IEnumerator<T> GetEnumerator ()
IEnumerator<T> IEnumerable<T>.GetEnumerator ()
{
return new StackItemEnumerator (top);
}
Expand Down Expand Up @@ -140,7 +144,7 @@ bool ICollection<T>.Remove (T item)
}
#endregion

class StackItem
internal class StackItem
{
public readonly StackItem Parent;
public readonly T Item;
Expand All @@ -152,32 +156,32 @@ public StackItem (StackItem parent, T item)
}
}

class StackItemEnumerator : IEnumerator<T>
public struct StackItemEnumerator : IEnumerator<T>
{
StackItem cur, first;

public StackItemEnumerator (StackItem cur)
internal StackItemEnumerator (StackItem cur)
{
this.cur = first = new StackItem (cur, default(T));
}

#region IDisposable implementation
void IDisposable.Dispose ()
public void Dispose ()
{
cur = first = null;
}
#endregion

#region IEnumerator implementation
bool IEnumerator.MoveNext ()
public bool MoveNext ()
{
if (cur == null)
return false;
cur = cur.Parent;
return cur != null;
}

void IEnumerator.Reset ()
public void Reset ()
{
cur = first;
}
Expand All @@ -190,7 +194,7 @@ void IEnumerator.Reset ()
#endregion

#region IEnumerator[T] implementation
T IEnumerator<T>.Current {
public T Current {
get {
return cur.Item;
}
Expand Down
25 changes: 13 additions & 12 deletions main/src/addins/CSharpBinding/Util/NameSyntaxExtensions.cs
Expand Up @@ -88,27 +88,28 @@ public NameSyntaxIterator(NameSyntax name)
_name = name;
}

public IEnumerator<NameSyntax> GetEnumerator()
public LinkedList<NameSyntax>.Enumerator GetEnumerator ()
{
var nodes = new LinkedList<NameSyntax>();
var nodes = new LinkedList<NameSyntax> ();

var currentNode = _name;
while (true)
{
if (currentNode.Kind() == SyntaxKind.QualifiedName)
{
while (true) {
if (currentNode.Kind () == SyntaxKind.QualifiedName) {
var qualifiedName = currentNode as QualifiedNameSyntax;
nodes.AddFirst(qualifiedName.Right);
nodes.AddFirst (qualifiedName.Right);
currentNode = qualifiedName.Left;
}
else
{
nodes.AddFirst(currentNode);
} else {
nodes.AddFirst (currentNode);
break;
}
}

return nodes.GetEnumerator();
return nodes.GetEnumerator ();
}

IEnumerator<NameSyntax> IEnumerable<NameSyntax>.GetEnumerator()
{
return GetEnumerator ();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
Expand Down

0 comments on commit 5bb28f8

Please sign in to comment.