Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocate less in GetTypeByMetadataName #68415

Merged
merged 61 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
633c3c6
Initial stubs for less allocs
CyrusNajmabadi Jun 1, 2023
6d739c5
Add type support
CyrusNajmabadi Jun 1, 2023
10f5607
Update helpers
CyrusNajmabadi Jun 1, 2023
1ef9d0e
remove
CyrusNajmabadi Jun 1, 2023
d41b95d
Break out type
CyrusNajmabadi Jun 1, 2023
8b3fddc
Fix
CyrusNajmabadi Jun 1, 2023
e02be95
Fix
CyrusNajmabadi Jun 1, 2023
ea4391b
Fix
CyrusNajmabadi Jun 1, 2023
badbdbb
Fix vb
CyrusNajmabadi Jun 1, 2023
afcacad
Update tests
CyrusNajmabadi Jun 1, 2023
439466b
ToString
CyrusNajmabadi Jun 1, 2023
03801fe
ReverT
CyrusNajmabadi Jun 1, 2023
a4c5d39
move more cases over to memory
CyrusNajmabadi Jun 1, 2023
ea6a516
move more cases over to memory
CyrusNajmabadi Jun 1, 2023
54f9eaa
Revert
CyrusNajmabadi Jun 1, 2023
cb5c485
Revert
CyrusNajmabadi Jun 1, 2023
cb95a2c
renames
CyrusNajmabadi Jun 1, 2023
a08f317
Simplify assert
CyrusNajmabadi Jun 1, 2023
0e1b119
Fix
CyrusNajmabadi Jun 1, 2023
6230338
Rename
CyrusNajmabadi Jun 1, 2023
0154b49
Merge remote-tracking branch 'upstream/main' into memoryLookup
CyrusNajmabadi Jun 1, 2023
864a406
Do the work for types as well
CyrusNajmabadi Jun 1, 2023
1ba1654
Move methods down
CyrusNajmabadi Jun 1, 2023
98cbf06
Ordering
CyrusNajmabadi Jun 1, 2023
6c03588
Simpler pattern
CyrusNajmabadi Jun 1, 2023
116a447
revert
CyrusNajmabadi Jun 1, 2023
ab9aca9
Add docs
CyrusNajmabadi Jun 1, 2023
120d13e
Remove another alloc
CyrusNajmabadi Jun 1, 2023
f052974
Shortcircuit common case
CyrusNajmabadi Jun 2, 2023
3ea0c33
Break helper into specific versions for compiler vs ide layers
CyrusNajmabadi Jun 2, 2023
66f1544
Use group-by
CyrusNajmabadi Jun 2, 2023
2ccbc86
remove
CyrusNajmabadi Jun 2, 2023
3584e8a
Merge remote-tracking branch 'upstream/main' into memoryLookup
CyrusNajmabadi Jun 7, 2023
ae9f5ec
Use explicit type
CyrusNajmabadi Jun 7, 2023
2e04867
make field
CyrusNajmabadi Jun 7, 2023
a0c934d
Throw unreachable
CyrusNajmabadi Jun 7, 2023
ef6dd44
use explicit type
CyrusNajmabadi Jun 7, 2023
e70e5b6
use explicit type
CyrusNajmabadi Jun 7, 2023
897366e
Don't allow
CyrusNajmabadi Jun 7, 2023
038d130
newline
CyrusNajmabadi Jun 7, 2023
9e1af08
use 'default'
CyrusNajmabadi Jun 7, 2023
58e2351
Be more explicit
CyrusNajmabadi Jun 7, 2023
5bb17be
REmove assert
CyrusNajmabadi Jun 7, 2023
5e0c905
Simplify
CyrusNajmabadi Jun 7, 2023
35a2062
Simplify
CyrusNajmabadi Jun 7, 2023
0a8daed
Add assert
CyrusNajmabadi Jun 7, 2023
c63380d
Move assert
CyrusNajmabadi Jun 7, 2023
d5c2a5d
Move local
CyrusNajmabadi Jun 7, 2023
23d1112
Add helper
CyrusNajmabadi Jun 7, 2023
ee6617f
use constnat
CyrusNajmabadi Jun 7, 2023
7f6c0c6
use constnat
CyrusNajmabadi Jun 7, 2023
68c465d
Simplify
CyrusNajmabadi Jun 7, 2023
179a4bf
Fix
CyrusNajmabadi Jun 7, 2023
84546bb
Simplify
CyrusNajmabadi Jun 7, 2023
64c8fc3
Update src/Compilers/CSharp/Portable/Symbols/NamespaceOrTypeSymbol.cs
CyrusNajmabadi Jun 7, 2023
5157ad1
Add assert
CyrusNajmabadi Jun 7, 2023
eec5c0d
Add assert back in
CyrusNajmabadi Jun 7, 2023
97fa6be
use helper
CyrusNajmabadi Jun 7, 2023
6724004
Use new arity scanning logic
CyrusNajmabadi Jun 8, 2023
333dca6
Simplify matching
CyrusNajmabadi Jun 8, 2023
a3d241a
Update src/Features/LanguageServer/Protocol/Handler/SpellCheck/Abstra…
CyrusNajmabadi Jun 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -132,12 +133,12 @@ public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a lot of hte change will be this mechanical switch from having NamedTypeSymbol/NamespaceSymbol move over to ROM over string.

Of note:

  1. I didn't do this for VB sicne we don't have traces showing a problem there (And i wanted to scope things small).
  2. I only updated GetTypeMembers, not GetMembers. The latter is not part of the GetTypeByMetadataName codepath, which is the worst offender in all our traces.
  3. I didn't expose this publicly, though we may want to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't expose this publicly, though we may want to.

Do we have evidence that customers are allocating string to call these APIs? IME these APIs tend to be called through hard coded constants, well known enum values or existing string. Not sure we'd save a lot by exposing ROM<string> members (happy to be proved wrong).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i'm basically saying: it's intentional that i'm not pushing for this to be public. and we should only drive that based on evidence that tthere is a need.

{
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
Expand Down Expand Up @@ -180,12 +181,12 @@ public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Symbols/ArrayTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,12 @@ public override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public override ImmutableArray<Symbol> GetMembers(string name)
return ImmutableArray<Symbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Roslyn.Utilities;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
Expand Down Expand Up @@ -190,7 +191,7 @@ public override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
/// <returns>An ImmutableArray containing all the types that are members of this symbol with the given name.
/// If this symbol has no type members with this name,
/// returns an empty ImmutableArray. Never returns null.</returns>
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand All @@ -201,7 +202,7 @@ public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
/// <returns>An ImmutableArray containing all the types that are members of this symbol with the given name and arity.
/// If this symbol has no type members with this name and arity,
/// returns an empty ImmutableArray. Never returns null.</returns>
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private FunctionPointerTypeSymbol(FunctionPointerMethodSymbol signature)
public override ImmutableArray<Symbol> GetMembers() => ImmutableArray<Symbol>.Empty;
public override ImmutableArray<Symbol> GetMembers(string name) => ImmutableArray<Symbol>.Empty;
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers() => ImmutableArray<NamedTypeSymbol>.Empty;
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name) => ImmutableArray<NamedTypeSymbol>.Empty;
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name) => ImmutableArray<NamedTypeSymbol>.Empty;
internal override TResult Accept<TArgument, TResult>(CSharpSymbolVisitor<TArgument, TResult> visitor, TArgument a) => visitor.VisitFunctionPointerType(this, a);
internal override ImmutableArray<NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList<TypeSymbol>? basesBeingResolved = null) => ImmutableArray<NamedTypeSymbol>.Empty;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ internal void SetExpression(BoundExpression expression)

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers() => throw ExceptionUtilities.Unreachable();

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name) => throw ExceptionUtilities.Unreachable();
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name) => throw ExceptionUtilities.Unreachable();

protected override ISymbol CreateISymbol() => throw ExceptionUtilities.Unreachable();

Expand Down
16 changes: 8 additions & 8 deletions src/Compilers/CSharp/Portable/Symbols/MergedNamespaceSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal sealed class MergedNamespaceSymbol : NamespaceSymbol
// The cachedLookup caches results of lookups on the constituent namespaces so that
// subsequent lookups for the same name are much faster than having to ask each of the
// constituent namespaces.
private readonly CachingDictionary<string, Symbol> _cachedLookup;
private readonly CachingDictionary<ReadOnlyMemory<char>, Symbol> _cachedLookup;

// GetMembers() is repeatedly called on merged namespaces in some IDE scenarios.
// This caches the result that is built by asking the 'cachedLookup' for a concatenated
Expand Down Expand Up @@ -93,7 +93,7 @@ private MergedNamespaceSymbol(NamespaceExtent extent, NamespaceSymbol containing
_extent = extent;
_namespacesToMerge = namespacesToMerge;
_containingNamespace = containingNamespace;
_cachedLookup = new CachingDictionary<string, Symbol>(SlowGetChildrenOfName, SlowGetChildNames, EqualityComparer<string>.Default);
_cachedLookup = new CachingDictionary<ReadOnlyMemory<char>, Symbol>(SlowGetChildrenOfName, SlowGetChildNames, ReadOnlyMemoryOfCharComparer.Instance);
_nameOpt = nameOpt;

#if DEBUG
Expand Down Expand Up @@ -132,7 +132,7 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok
/// Method that is called from the CachingLookup to lookup the children of a given name.
/// Looks in all the constituent namespaces.
/// </summary>
private ImmutableArray<Symbol> SlowGetChildrenOfName(string name)
private ImmutableArray<Symbol> SlowGetChildrenOfName(ReadOnlyMemory<char> name)
{
ArrayBuilder<NamespaceSymbol> namespaceSymbols = null;
var otherSymbols = ArrayBuilder<Symbol>.GetInstance();
Expand Down Expand Up @@ -166,15 +166,15 @@ private ImmutableArray<Symbol> SlowGetChildrenOfName(string name)
/// Method that is called from the CachingLookup to get all child names. Looks in all
/// constituent namespaces.
/// </summary>
private HashSet<string> SlowGetChildNames(IEqualityComparer<string> comparer)
private HashSet<ReadOnlyMemory<char>> SlowGetChildNames(IEqualityComparer<ReadOnlyMemory<char>> comparer)
{
var childNames = new HashSet<string>(comparer);
var childNames = new HashSet<ReadOnlyMemory<char>>(comparer);

foreach (var ns in _namespacesToMerge)
{
foreach (var child in ns.GetMembersUnordered())
{
childNames.Add(child.Name);
childNames.Add(child.Name.AsMemory());
}
}

Expand Down Expand Up @@ -218,7 +218,7 @@ public override ImmutableArray<Symbol> GetMembers()
return _allMembers;
}

public override ImmutableArray<Symbol> GetMembers(string name)
public override ImmutableArray<Symbol> GetMembers(ReadOnlyMemory<char> name)
{
return _cachedLookup[name];
}
Expand All @@ -233,7 +233,7 @@ public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return ImmutableArray.CreateRange<NamedTypeSymbol>(GetMembers().OfType<NamedTypeSymbol>());
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
// TODO - This is really inefficient. Creating a new array on each lookup needs to fixed!
return ImmutableArray.CreateRange<NamedTypeSymbol>(_cachedLookup[name].OfType<NamedTypeSymbol>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ private ImmutableArray<CSharpAttributeData> GetCustomAttributesFilterCompilerAtt
}

internal void OnNewTypeDeclarationsLoaded(
Dictionary<string, ImmutableArray<PENamedTypeSymbol>> typesDict)
Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>> typesDict)
{
bool keepLookingForDeclaredCorTypes = (_ordinal == 0 && _assemblySymbol.KeepLookingForDeclaredSpecialTypes);

Expand Down Expand Up @@ -691,7 +691,7 @@ internal override CharSet? DefaultMarshallingCharSet
internal NamedTypeSymbol LookupTopLevelMetadataTypeWithNoPiaLocalTypeUnification(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
{
NamedTypeSymbol? result;
var scope = (PENamespaceSymbol?)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments);
var scope = (PENamespaceSymbol?)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegmentsMemory);
Copy link
Member Author

@CyrusNajmabadi CyrusNajmabadi Jun 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is one of the heaviest hitters. we used to break the FQN into N string pieces (each of which copies the data) for the namespace portion of the FQN. Now we just have an array of ROM chunks. The chunks are effectively free (lightweight structs), though we still pay for an array allocation here. Ideally we could remove that as well with a specialized structure. I do see these arrays still show up as about 1% of allocs (the same as before).


if ((object?)scope == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
/// </summary>
internal abstract class PENamedTypeSymbol : NamedTypeSymbol
{
private static readonly Dictionary<string, ImmutableArray<PENamedTypeSymbol>> s_emptyNestedTypes = new Dictionary<string, ImmutableArray<PENamedTypeSymbol>>(EmptyComparer.Instance);
private static readonly Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>> s_emptyNestedTypes =
new Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>>(EmptyReadOnlyMemoryOfCharComparer.Instance);

private readonly NamespaceOrTypeSymbol _container;
private readonly TypeDefinitionHandle _handle;
Expand Down Expand Up @@ -60,7 +61,7 @@ internal abstract class PENamedTypeSymbol : NamedTypeSymbol
/// A map of types immediately contained within this type
/// grouped by their name (case-sensitively).
/// </summary>
private Dictionary<string, ImmutableArray<PENamedTypeSymbol>> _lazyNestedTypes;
private Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>> _lazyNestedTypes;

/// <summary>
/// Lazily initialized by TypeKind property.
Expand Down Expand Up @@ -1509,7 +1510,7 @@ public override ImmutableArray<Symbol> GetMembers(string name)

// nested types are not common, but we need to check just in case
ImmutableArray<PENamedTypeSymbol> t;
if (_lazyNestedTypes.TryGetValue(name, out t))
if (_lazyNestedTypes.TryGetValue(name.AsMemory(), out t))
{
m = m.Concat(StaticCast<Symbol>.From(t));
}
Expand Down Expand Up @@ -1578,7 +1579,7 @@ private void EnsureNestedTypesAreLoaded()
}
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
EnsureNestedTypesAreLoaded();

Expand All @@ -1592,7 +1593,7 @@ public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return GetTypeMembers(name).WhereAsArray((type, arity) => type.Arity == arity, arity);
}
Expand Down Expand Up @@ -2056,14 +2057,14 @@ private static Dictionary<string, ImmutableArray<Symbol>> GroupByName(ArrayBuild
return symbols.ToDictionary(s => s.Name, StringOrdinalComparer.Instance);
}

private static Dictionary<string, ImmutableArray<PENamedTypeSymbol>> GroupByName(ArrayBuilder<PENamedTypeSymbol> symbols)
private static Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>> GroupByName(ArrayBuilder<PENamedTypeSymbol> symbols)
{
if (symbols.Count == 0)
{
return s_emptyNestedTypes;
}

return symbols.ToDictionary(s => s.Name, StringOrdinalComparer.Instance);
return symbols.ToDictionary(s => s.Name.AsMemory(), ReadOnlyMemoryOfCharComparer.Instance);
}

internal override UseSiteInfo<AssemblySymbol> GetUseSiteInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ internal abstract class PENamespaceSymbol
/// A map of namespaces immediately contained within this namespace
/// mapped by their name (case-sensitively).
/// </summary>
protected Dictionary<string, PENestedNamespaceSymbol> lazyNamespaces;
protected Dictionary<ReadOnlyMemory<char>, PENestedNamespaceSymbol> lazyNamespaces;

/// <summary>
/// A map of types immediately contained within this namespace
/// grouped by their name (case-sensitively).
/// </summary>
protected Dictionary<string, ImmutableArray<PENamedTypeSymbol>> lazyTypes;
protected Dictionary<ReadOnlyMemory<char>, ImmutableArray<PENamedTypeSymbol>> lazyTypes;

/// <summary>
/// A map of NoPia local types immediately contained in this assembly.
Expand Down Expand Up @@ -87,7 +87,7 @@ private ImmutableArray<NamedTypeSymbol> GetMemberTypesPrivate()
return StaticCast<NamedTypeSymbol>.From(_lazyFlattenedTypes);
}

public sealed override ImmutableArray<Symbol> GetMembers(string name)
public sealed override ImmutableArray<Symbol> GetMembers(ReadOnlyMemory<char> name)
{
EnsureAllMembersLoaded();

Expand Down Expand Up @@ -121,7 +121,7 @@ public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return GetMemberTypesPrivate();
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
EnsureAllMembersLoaded();

Expand All @@ -132,7 +132,7 @@ public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string nam
: ImmutableArray<NamedTypeSymbol>.Empty;
}

public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public sealed override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return GetTypeMembers(name).WhereAsArray((type, arity) => type.Arity == arity, arity);
}
Expand Down Expand Up @@ -224,12 +224,12 @@ private void LazyInitializeNamespaces(
{
if (this.lazyNamespaces == null)
{
var namespaces = new Dictionary<string, PENestedNamespaceSymbol>(StringOrdinalComparer.Instance);
var namespaces = new Dictionary<ReadOnlyMemory<char>, PENestedNamespaceSymbol>(ReadOnlyMemoryOfCharComparer.Instance);

foreach (var child in childNamespaces)
{
var c = new PENestedNamespaceSymbol(child.Key, this, child.Value);
namespaces.Add(c.Name, c);
namespaces.Add(c.Name.AsMemory(), c);
}

Interlocked.CompareExchange(ref this.lazyNamespaces, namespaces, null);
Expand Down Expand Up @@ -276,7 +276,7 @@ private void LazyInitializeTypes(IEnumerable<IGrouping<string, TypeDefinitionHan
}
}

var typesDict = children.ToDictionary(c => c.Name, StringOrdinalComparer.Instance);
var typesDict = children.ToDictionary(c => c.Name.AsMemory(), ReadOnlyMemoryOfCharComparer.Instance);
children.Free();

if (noPiaLocalTypes != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@

#nullable disable

using System.Collections.Generic;
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Diagnostics;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
Expand Down Expand Up @@ -115,12 +112,12 @@ public override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}

public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(ReadOnlyMemory<char> name, int arity)
{
return ImmutableArray<NamedTypeSymbol>.Empty;
}
Expand All @@ -130,7 +127,7 @@ public override ImmutableArray<Symbol> GetMembers()
return ImmutableArray<Symbol>.Empty;
}

public override ImmutableArray<Symbol> GetMembers(string name)
public override ImmutableArray<Symbol> GetMembers(ReadOnlyMemory<char> name)
{
return ImmutableArray<Symbol>.Empty;
}
Expand Down
Loading