Uh oh!
There was an error while loading. Please reload this page.
Optimize try_eval_bits to avoid layout queries - #64673
Conversation
Mark-Simulacrum
commented
Sep 21, 2019
@bors try @rust-timer queue |
rust-timer
commented
Sep 21, 2019
Awaiting bors try build completion |
bors
commented
Sep 21, 2019
Optimize match checking to avoid layout queries In code with large, single-value match statements, we were previously spending a lot of time running layout_of for the primitive types (integers, chars) -- which is essentially useless. This optimizes the code to avoid those query calls by directly obtaining the size for these types, when possible. We fallback to the (slower) previous code if that fails, so this is not a behavior change. r? @Centril who I believe knows this code enough, but if not feel free to re-assign
Centril
commented
Sep 21, 2019
bors
commented
Sep 22, 2019
☀️ Try build successful - checks-azure |
rust-timer
commented
Sep 22, 2019
Queued 9b2e58c with parent ed8b708, future comparison URL. |
rust-timer
commented
Sep 22, 2019
Finished benchmarking try commit 9b2e58c, comparison URL. |
bjorn3
commented
Sep 22, 2019
unicode_normalization is ~30% faster! 3 other benchea got ~2% slower. The rest is stable. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
511352c to
9c62117CompareMark-Simulacrum
commented
Sep 22, 2019
Okay, moved into the try_eval_bits function -- locally that shows that this unicode_normalization is a bit slower (~0.05s) after doing so, but that might be noise (although I get pretty consistent results). Let's get some official results though @bors try @rust-timer queue |
rust-timer
commented
Sep 22, 2019
Awaiting bors try build completion |
bors
commented
Sep 22, 2019
Optimize match checking to avoid layout queries In code with large, single-value match statements, we were previously spending a lot of time running layout_of for the primitive types (integers, chars) -- which is essentially useless. This optimizes the code to avoid those query calls by directly obtaining the size for these types, when possible. We fallback to the (slower) previous code if that fails, so this is not a behavior change. r? @Centril who I believe knows this code enough, but if not feel free to re-assign
bors
commented
Sep 22, 2019
☀️ Try build successful - checks-azure |
rust-timer
commented
Sep 22, 2019
Queued 64687bb with parent 4ff32c0, future comparison URL. |
bjorn3
commented
Sep 22, 2019
Compilation of four crates failed during benchmarking: |
rust-timer
commented
Sep 22, 2019
Finished benchmarking try commit 64687bb, comparison URL. |
Mark-Simulacrum
commented
Sep 22, 2019
Failures are unrelated to this PR; they're due to newly introduced self-profile functionality for rustc. |
Mark-Simulacrum
commented
Sep 23, 2019
Looks like ~no difference which is good -- more general code is probably better. It's probably more likely this would've had a difference with const generics being used in the set of crate benchmarks. @oli-obk I believe this should be ready to merge. |
oli-obk
commented
Sep 23, 2019
@bors r+ |
bors
commented
Sep 23, 2019
📌 Commit 9c62117 has been approved by |
Centril
commented
Sep 23, 2019
@bors rollup=never |
Centril
commented
Sep 28, 2019
@bors p=3 |
bors
commented
Sep 29, 2019
⌛ Testing commit 9c62117 with merge eea282a8233db92be72b4de43c575023a00f07f8... |
rust-highfive
commented
Sep 29, 2019
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
bors
commented
Sep 29, 2019
💔 Test failed - checks-azure |
This specifically targets match checking, but is possibly more widely useful as well. In code with large, single-value match statements, we were previously spending a lot of time running layout_of for the primitive types (integers, chars) -- which is essentially useless. This optimizes the code to avoid those query calls by directly obtaining the size for these types, when possible. It may be worth considering adding a `size_of` query in the future which might be far faster, especially if specialized for "const" cases -- match arms being the most obvious example. It's possibly such a function would benefit from *not* being a query as well, since it's trivially evaluatable from the sty for many cases whereas a query needs to hash the input and such.
9c62117 to
06c6e75CompareMark-Simulacrum
commented
Sep 29, 2019
@bors r=oli-obk |
bors
commented
Sep 29, 2019
📌 Commit 06c6e75 has been approved by |
bors
commented
Sep 29, 2019
Optimize try_eval_bits to avoid layout queries This specifically targets match checking, but is possibly more widely useful as well. In code with large, single-value match statements, we were previously spending a lot of time running layout_of for the primitive types (integers, chars) -- which is essentially useless. This optimizes the code to avoid those query calls by directly obtaining the size for these types, when possible. It may be worth considering adding a `size_of` query in the future which might be far faster, especially if specialized for "const" cases -- match arms being the most obvious example. It's possibly such a function would benefit from *not* being a query as well, since it's trivially evaluatable from the sty for many cases whereas a query needs to hash the input and such.
bors
commented
Sep 30, 2019
☀️ Test successful - checks-azure |
The `if let Some(val) = value.try_eval_bits(...)` branch in `from_const()` is very hot for the `unicode_normalization` benchmark. This commit introduces a special-case alternative for scalars that avoids `try_eval_bits()` and all the functions it calls (`Const::eval()`, `ConstValue::try_to_bits()`, `ConstValue::try_to_scalar()`, and `Scalar::to_bits()`), instead extracting the result immediately. The type and value checking done by `Scalar::to_bits()` is replicated by moving it into a new function `Scalar::check_raw()` and using that new function in the special case. PR rust-lang#64673 introduced some special-case handling of scalar types in `Const::try_eval_bits()`. This handling is now moved out of that function into the new `IntRange::integral_size_and_signed_bias` function. This commit reduces the instruction count for `unicode_normalization-check-clean` by about 10%.
This specifically targets match checking, but is possibly more widely
useful as well. In code with large, single-value match statements, we
were previously spending a lot of time running layout_of for the
primitive types (integers, chars) -- which is essentially useless. This
optimizes the code to avoid those query calls by directly obtaining the
size for these types, when possible.
It may be worth considering adding a
size_ofquery in the future whichmight be far faster, especially if specialized for "const" cases --
match arms being the most obvious example. It's possibly such a function
would benefit from not being a query as well, since it's trivially
evaluatable from the sty for many cases whereas a query needs to hash
the input and such.