about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Bergdoll <lukas.bergdoll@gmail.com>2023-02-11 09:32:52 +0100
committerLukas Bergdoll <lukas.bergdoll@gmail.com>2023-02-11 09:32:52 +0100
commitee0376c368c50c7dadc84801e88cfdbf250b92a4 (patch)
tree1c5617ae49bd38e79acea9ee9198e27f8f76a79a
parent7e072199a6e650698c2f5f1e1053b20d48be43d3 (diff)
downloadrust-ee0376c368c50c7dadc84801e88cfdbf250b92a4.tar.gz
rust-ee0376c368c50c7dadc84801e88cfdbf250b92a4.zip
Split branches in heapsort child selection
This allows even better code-gen, cmp + adc. While also more clearly
communicating the intent.
-rw-r--r--library/core/src/slice/sort.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 990540f55f5..8f02a446670 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -198,7 +198,12 @@ where
             }
 
             // Choose the greater child.
-            child += (child + 1 < v.len() && is_less(&v[child], &v[child + 1])) as usize;
+            if child + 1 < v.len() {
+                // We need a branch to be sure not to out-of-bounds index,
+                // but it's highly predictable.  The comparison, however,
+                // is better done branchless, especially for primitives.
+                child += is_less(&v[child], &v[child + 1]) as usize;
+            }
 
             // Stop if the invariant holds at `node`.
             if !is_less(&v[node], &v[child]) {