Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 6 additions & 26 deletions src/Common/src/System/Collections/HashHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ namespace System.Collections
{
internal static class HashHelpers
{
private const Int32 HashPrime = 101;

// Table of prime numbers to use as hash table sizes.
// A typical resize algorithm would pick the smallest prime number in this array
// that is larger than twice the previous capacity.
Expand All @@ -41,23 +39,12 @@ internal static class HashHelpers
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369 };

public static bool IsPrime(int candidate)
{
if ((candidate & 1) != 0)
{
int limit = (int)Math.Sqrt(candidate);
for (int divisor = 3; divisor <= limit; divisor += 2)
{
if ((candidate % divisor) == 0)
return false;
}
return true;
}
return (candidate == 2);
}

1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369, 8639249, 10367101,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What algorithm/formula did you use to expand the table?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I plotted the existing points in Excel. I noticed that, except for the first few points, the rest rose by a factor of 1.2 times. So I wrote a little program to compute them so they would match the same pattern.

  1. take the last prime, multiply it by 1.2
  2. find the next prime >= the number in computed in step 1.
  3. goto 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is going to change allocations in certain cases. For example, before your change, adding 8M items to a HashSet<int> would result in the _slots and _buckets arrays ending at 11998949 in length, and after your change they'll be 12440537 in length (~400K elements each, ~4% increase). Whether that's good or bad for the scenarios that hit this, I don't know. I do like that we can simplify the code by expanding out the table, but we should understand the full ramifications of doing so before such a change is made.

12440537, 14928671, 17914409, 21497293, 25796759, 30956117, 37147349, 44576837, 53492207, 64190669,
77028803, 92434613, 110921543, 133105859, 159727031, 191672443, 230006941, 276008387, 331210079,
397452101, 476942527, 572331049, 686797261, 824156741, 988988137, 1186785773, 1424142949, 1708971541,
2050765853, MaxPrimeArrayLength };

public static int GetPrime(int min)
{
if (min < 0)
Expand All @@ -70,13 +57,6 @@ public static int GetPrime(int min)
if (prime >= min) return prime;
}

//outside of our predefined table.
//compute the hard way.
for (int i = (min | 1); i < Int32.MaxValue; i += 2)
{
if (IsPrime(i) && ((i - 1) % HashPrime != 0))
return i;
}
return min;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1013,8 +1013,6 @@ private void IncreaseCapacity()
/// </summary>
private void SetCapacity(int newSize, bool forceNewHashCodes)
{
Debug.Assert(HashHelpers.IsPrime(newSize), "New size is not prime!");

Debug.Assert(_buckets != null, "SetCapacity called on a set with no elements");

Slot[] newSlots = new Slot[newSize];
Expand Down