From c0ee7b26255814b7aaddc6a682b1df75ad2ae009 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 2 Dec 2024 17:38:22 +0100 Subject: [PATCH 1/2] Improve performance by optimizing bundle mergin logic. While merging two bundles, the `merge_bundles` function appends two sorted vectors and sort the resulting vector again. This approach used to be fast in most cases, but rustc 1.81 introduced changes in sorting algorithm that made `sort_unstable_by_key` to behave very bad with vectors are that are almost sorted. This introduces an optimization consisting in handling the special case where the vector being appended contains a single item differently. This case is very common, and there's a benefit in handling it differently both with rust 1.81 and with earlier versions. --- src/ion/merge.rs | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/ion/merge.rs b/src/ion/merge.rs index f921620f..f503acf1 100644 --- a/src/ion/merge.rs +++ b/src/ion/merge.rs @@ -170,19 +170,33 @@ impl<'a, F: Function> Env<'a, F> { ranges_to ); - // Two non-empty lists of LiveRanges: concatenate and - // sort. This is faster than a mergesort-like merge into a new - // list, empirically. let empty_vec = LiveRangeList::new_in(self.ctx.bump()); - let from_list = core::mem::replace(&mut self.bundles[from].ranges, empty_vec); + let mut from_list = core::mem::replace(&mut self.bundles[from].ranges, empty_vec); for entry in &from_list { self.ranges[entry.index].bundle = to; } - self.bundles[to].ranges.extend_from_slice(&from_list[..]); - self.bundles[to] - .ranges - .sort_unstable_by_key(|entry| entry.range.from); + if from_list.len() == 1 { + // Optimize for the common case where `from_list` contains a single + // item. Using a binary search to find the insertion point and then + // calling `insert` is more efficient than re-sorting the entire + // list, specially after the changes in sorting algorithms introduced + // in rustc 1.81. + // See: https://github.com/bytecodealliance/regalloc2/issues/203 + let single_entry = from_list.pop().unwrap(); + let pos = self.bundles[to] + .ranges + .binary_search_by_key(&single_entry.range.from, |entry| entry.range.from) + .unwrap_or_else(|pos| pos); + self.bundles[to].ranges.insert(pos, single_entry); + } else { + // Two non-empty lists of LiveRanges: concatenate and sort. This is + // faster than a mergesort-like merge into a new list, empirically. + self.bundles[to].ranges.extend_from_slice(&from_list[..]); + self.bundles[to] + .ranges + .sort_unstable_by_key(|entry| entry.range.from); + } if self.annotations_enabled { trace!("merging: merged = {:?}", self.bundles[to].ranges); From b3be82e03aeb8f5c51988f7e2757c30c8d3a209e Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Mon, 2 Dec 2024 09:19:56 -0800 Subject: [PATCH 2/2] Update deny.toml. --- deny.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deny.toml b/deny.toml index 42238753..8522b2c1 100644 --- a/deny.toml +++ b/deny.toml @@ -1,3 +1,4 @@ +[graph] targets = [ { triple = "x86_64-unknown-linux-gnu" }, { triple = "x86_64-apple-darwin" }, @@ -7,8 +8,6 @@ targets = [ # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] -vulnerability = "deny" -unmaintained = "deny" yanked = "deny" ignore = [] @@ -19,6 +18,7 @@ allow = [ "Apache-2.0", "MIT", "Unicode-DFS-2016", + "Unicode-3.0", ] # https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html