about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2024-01-16 10:19:23 -0500
committerMark Rousskov <mark.simulacrum@gmail.com>2024-01-16 10:21:55 -0500
commit1696148a894f6e5fd8857400ebede44dedee0e2c (patch)
tree68de92170ca67cbd0993854b2786d7ba362ab26f
parent665d2c6f2c49f1b9710f201b341354769cef3f94 (diff)
downloadrust-1696148a894f6e5fd8857400ebede44dedee0e2c.tar.gz
rust-1696148a894f6e5fd8857400ebede44dedee0e2c.zip
Merge into larger interval set
This reduces the work done while merging rows. In at least one case
(issue 50450), we have thousands of union([range], [20,000 ranges]),
which previously inserted each of the 20,000 ranges one by one. Now we
only insert one range into the right hand set after copying the set
over.
-rw-r--r--compiler/rustc_index/src/interval.rs6
1 files changed, 6 insertions, 0 deletions
diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs
index d3cf267dc9d..0c1180b3e98 100644
--- a/compiler/rustc_index/src/interval.rs
+++ b/compiler/rustc_index/src/interval.rs
@@ -236,6 +236,12 @@ impl<I: Idx> IntervalSet<I> {
         I: Step,
     {
         assert_eq!(self.domain, other.domain);
+        if self.map.len() < other.map.len() {
+            let backup = self.clone();
+            self.map.clone_from(&other.map);
+            return self.union(&backup);
+        }
+
         let mut did_insert = false;
         for range in other.iter_intervals() {
             did_insert |= self.insert_range(range);