Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Make some Dictionary code smaller (#10993)
Browse files Browse the repository at this point in the history
Store a reference to the relevant entry at the start of the loop to avoid indexing `entries` multiple times.
This avoids some redundant range checks in `Remove` and allows the elimination of a duplicate `index++` in `Enumerator.MoveNext`.

Saves ~7KB of code.
  • Loading branch information
mikedn authored and jkotas committed Apr 15, 2017
1 parent dbc3557 commit 6cb9a6f
Showing 1 changed file with 42 additions and 32 deletions.
74 changes: 42 additions & 32 deletions src/mscorlib/src/System/Collections/Generic/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,7 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)

if (buckets == null) Initialize(0);
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int targetBucket = hashCode % buckets.Length;

int targetBucket = hashCode % buckets.Length;
#if FEATURE_RANDOMIZED_STRING_HASHING
int collisionCount = 0;
#endif
Expand All @@ -452,7 +451,6 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)

return false;
}

#if FEATURE_RANDOMIZED_STRING_HASHING
collisionCount++;
#endif
Expand Down Expand Up @@ -599,27 +597,33 @@ public bool Remove(TKey key)
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
int i = buckets[bucket];
while (i >= 0)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
ref Entry entry = ref entries[i];

if (entry.hashCode == hashCode && comparer.Equals(entry.key, key))
{
if (last < 0)
{
buckets[bucket] = entries[i].next;
buckets[bucket] = entry.next;
}
else
{
entries[last].next = entries[i].next;
entries[last].next = entry.next;
}
entries[i].hashCode = -1;
entries[i].next = freeList;
entries[i].key = default(TKey);
entries[i].value = default(TValue);
entry.hashCode = -1;
entry.next = freeList;
entry.key = default(TKey);
entry.value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}

last = i;
i = entry.next;
}
}
return false;
Expand All @@ -640,30 +644,36 @@ public bool Remove(TKey key, out TValue value)
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
int i = buckets[bucket];
while (i >= 0)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
ref Entry entry = ref entries[i];

if (entry.hashCode == hashCode && comparer.Equals(entry.key, key))
{
if (last < 0)
{
buckets[bucket] = entries[i].next;
buckets[bucket] = entry.next;
}
else
{
entries[last].next = entries[i].next;
entries[last].next = entry.next;
}

value = entries[i].value;
value = entry.value;

entries[i].hashCode = -1;
entries[i].next = freeList;
entries[i].key = default(TKey);
entries[i].value = default(TValue);
entry.hashCode = -1;
entry.next = freeList;
entry.key = default(TKey);
entry.value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}

last = i;
i = entry.next;
}
}
value = default(TValue);
Expand Down Expand Up @@ -955,13 +965,13 @@ public bool MoveNext()
// dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
while ((uint)index < (uint)dictionary.count)
{
if (dictionary.entries[index].hashCode >= 0)
ref Entry entry = ref dictionary.entries[index++];

if (entry.hashCode >= 0)
{
current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
index++;
current = new KeyValuePair<TKey, TValue>(entry.key, entry.value);
return true;
}
index++;
}

index = dictionary.count + 1;
Expand Down Expand Up @@ -1231,13 +1241,13 @@ public bool MoveNext()

while ((uint)index < (uint)dictionary.count)
{
if (dictionary.entries[index].hashCode >= 0)
ref Entry entry = ref dictionary.entries[index++];

if (entry.hashCode >= 0)
{
currentKey = dictionary.entries[index].key;
index++;
currentKey = entry.key;
return true;
}
index++;
}

index = dictionary.count + 1;
Expand Down Expand Up @@ -1459,13 +1469,13 @@ public bool MoveNext()

while ((uint)index < (uint)dictionary.count)
{
if (dictionary.entries[index].hashCode >= 0)
ref Entry entry = ref dictionary.entries[index++];

if (entry.hashCode >= 0)
{
currentValue = dictionary.entries[index].value;
index++;
currentValue = entry.value;
return true;
}
index++;
}
index = dictionary.count + 1;
currentValue = default(TValue);
Expand Down

0 comments on commit 6cb9a6f

Please sign in to comment.