Skip to content

Commit

Permalink
* Registry.GetSubKeyNames : Remove List copy to Array (#79345)
Browse files Browse the repository at this point in the history
* * Replace List by string[] to avoid List.ToArray() copy (it must handle rare cases where there are more or less elements during the loop).

* // Shrink array to fit found items, if necessary
  • Loading branch information
Poppyto authored Jan 2, 2023
1 parent 64187f4 commit a08cfcb
Showing 1 changed file with 23 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ public unsafe string[] GetValueNames()
return Array.Empty<string>();
}

var names = new List<string>(values);
string[] names = new string[values];

// Names in the registry aren't usually very long, although they can go to as large
// as 16383 characters (MaxValueLength).
Expand All @@ -888,6 +888,7 @@ public unsafe string[] GetValueNames()
// only if needed.

char[]? name = ArrayPool<char>.Shared.Rent(100);
int cpt = 0;

try
{
Expand All @@ -896,7 +897,7 @@ public unsafe string[] GetValueNames()

while ((result = Interop.Advapi32.RegEnumValue(
_hkey,
names.Count,
cpt,
name,
ref nameLength,
0,
Expand All @@ -909,7 +910,12 @@ public unsafe string[] GetValueNames()
// The size is only ever reported back correctly in the case
// of ERROR_SUCCESS. It will almost always be changed, however.
case Interop.Errors.ERROR_SUCCESS:
names.Add(new string(name, 0, nameLength));
if (cpt >= names.Length) // possible new item during loop
{
Array.Resize(ref names, names.Length * 2);
}

names[cpt++] = new string(name, 0, nameLength);
break;
case Interop.Errors.ERROR_MORE_DATA:
if (IsPerfDataKey())
Expand All @@ -919,9 +925,15 @@ public unsafe string[] GetValueNames()
// to be big enough however. 8 characters is the largest
// known name. The size isn't returned, but the string is
// null terminated.

if (cpt >= names.Length) // possible new item during loop
{
Array.Resize(ref names, names.Length * 2);
}

fixed (char* c = &name[0])
{
names.Add(new string(c));
names[cpt++] = new string(c);
}
}
else
Expand Down Expand Up @@ -949,7 +961,13 @@ public unsafe string[] GetValueNames()
ArrayPool<char>.Shared.Return(name);
}

return names.ToArray();
// Shrink array to fit found items, if necessary
if (cpt < names.Length)
{
Array.Resize(ref names, cpt);
}

return names;
}

/// <summary>Retrieves the specified value. <b>null</b> is returned if the value doesn't exist</summary>
Expand Down

0 comments on commit a08cfcb

Please sign in to comment.