-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Remove use of the modulo operator in Queue.Enumerator #11101
Conversation
👍 |
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.
This seems like unnecessary complexity. I'd rather leave it as it was and then see the JIT improve so that this and all other such cases benefit. This new code is, IMO, much harder to follow than the previous version.
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.
👍
@stephentoub PR feedback is done; thanks for reviewing. |
Test Innerloop OSX Debug Build and Test |
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.
As previously commented, is this really saving enough / providing enough value to be worth churning the code, making it harder to read, etc.? What measurement are you using?
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.
Let's keep this PR to exactly what it was meant to be about: removing the modulo. If it's then justifiable to do further surgery, that can be done separately.
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.
@stephentoub OK, sure. I've done testing and omitting the result
variable doesn't seem to change much, so the changes in this PR are now as minimal as possible.
LGTM. Thanks for the improvement, @jamesqo. |
Currently Queue.Enumerator.MoveNext uses the modulo operator, which is very slow (
idiv
has lots of latency compared to other instructions). Additionally, the method it calls that uses it (GetElement
) is not being inlined.This PR removes such use of the % operator and replaces it with simple branch/subtraction operations. I also separated a part of the method that will not get called very often into a new
MoveNextRare
function, which decreases the code size for the main codepath significantly.Disassembly before and after
I did some benchmarking and this change brings the average running time for a foreach loop from ~2.9s to ~1.7s. (microbenchmark)
Fixes #10854
cc @ianhays, @GSPP
edit: forgot to cc @omariom who wrote #2515