-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
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.
7b606b4
to
e890079
Compare
jit-diff summary:
|
Using This approach can be used in other places ( |
TryInsert could benefit from that too. |
It's in the same boat as |
I played with it when prerelease Roslyn bits. There were small improvements in perf and the size of the loop. But I checked it on the full framework and for primitive keys only. |
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this change from the for loop to a while impact the code gen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, they all look like while
loops to JIT and it transforms them into do
-while
loops.
Dictionary.Remove
diff: https://gist.github.com/mikedn/ccf5673a57ef7182c961b4e387ab5c0e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's what I'd have guessed, thanks. So this change was just for consistency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean the change from for
to while
? It's because entries[i]
was used in the iterator expression of the for
statement and there entry
is not available.
I could have kept for
and only move the iterator expression to the end of the for
body. But it's not a typical for
anyway so I changed it to while
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Ok.
While I'm at it here's a |
Thanks! |
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 duplicateindex++
inEnumerator.MoveNext
.Saves ~7KB of code.
Fixes #10883