From 783e56790808d285a3ab1122062509dd905103c8 Mon Sep 17 00:00:00 2001 From: Ben Ruijl Date: Fri, 11 Oct 2024 14:36:31 +0200 Subject: [PATCH] Switch to binary search for large additions --- src/normalize.rs | 78 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/src/normalize.rs b/src/normalize.rs index 2d4b8133..939a2c80 100644 --- a/src/normalize.rs +++ b/src/normalize.rs @@ -1420,21 +1420,53 @@ impl<'a> AtomView<'a> { return; } - let mut found = false; - for x in a1.iter() { - // TODO: find the position of rhs in self with a binary search - if found { - a.extend(x); - continue; - } - - match x.cmp_terms(&rhs) { - Ordering::Less => { + if a1.get_nargs() < 50 { + let mut found = false; + for x in a1.iter() { + if found { a.extend(x); + continue; + } + + match x.cmp_terms(&rhs) { + Ordering::Less => { + a.extend(x); + } + Ordering::Equal => { + found = true; + b.set_from_view(&x); + if b.merge_terms(rhs, &mut helper) { + if let AtomView::Num(n) = a.as_view() { + if !n.is_zero() { + a.extend(b.as_view()); + } + } else { + a.extend(b.as_view()); + } + } else { + unreachable!("Equal terms do not merge"); + } + } + Ordering::Greater => { + found = true; + a.extend(rhs); + a.extend(x); + } } - Ordering::Equal => { - found = true; - b.set_from_view(&x); + } + + if !found { + a.extend(rhs); + } + } else { + let v: Vec<_> = a1.iter().collect(); + match v.binary_search_by(|a| a.cmp_terms(&rhs)) { + Ok(p) => { + for x in v.iter().take(p) { + a.extend(*x); + } + + b.set_from_view(&v[p]); if b.merge_terms(rhs, &mut helper) { if let AtomView::Num(n) = a.as_view() { if !n.is_zero() { @@ -1446,19 +1478,25 @@ impl<'a> AtomView<'a> { } else { unreachable!("Equal terms do not merge"); } + + for x in v.iter().skip(p + 1) { + a.extend(*x); + } } - Ordering::Greater => { - found = true; + Err(p) => { + for x in v.iter().take(p) { + a.extend(*x); + } + a.extend(rhs); - a.extend(x); + + for x in v.iter().skip(p) { + a.extend(*x); + } } } } - if !found { - a.extend(rhs); - } - a.set_normalized(true); } else if let AtomView::Add(_) = rhs { rhs.add_normalized(*self, ws, out);