3.7.6, 3.7.7 Optimize multiexp implementations

This commit is contained in:
Luke Parker 2023-03-02 06:12:02 -05:00
parent e5329b42e6
commit 1d2ebdca62
No known key found for this signature in database
2 changed files with 35 additions and 13 deletions

View file

@ -15,8 +15,10 @@ where
let mut res = G::identity(); let mut res = G::identity();
for n in (0 .. bits[0].len()).rev() { for n in (0 .. bits[0].len()).rev() {
for _ in 0 .. window { if n != (bits[0].len() - 1) {
res = res.double(); for _ in 0 .. window {
res = res.double();
}
} }
let mut buckets = vec![G::identity(); 2_usize.pow(window.into())]; let mut buckets = vec![G::identity(); 2_usize.pow(window.into())];
@ -49,18 +51,32 @@ where
} }
} }
let mut buckets = vec![G::identity(); 2_usize.pow(window.into())]; // Use None to represent identity since is_none is likely faster than is_identity
let mut buckets = vec![None; 2_usize.pow(window.into())];
for p in 0 .. bits.len() { for p in 0 .. bits.len() {
let nibble = usize::from(bits[p][n]); let nibble = usize::from(bits[p][n]);
if nibble != 0 { if nibble != 0 {
buckets[nibble] += pairs[p].1; if let Some(bucket) = buckets[nibble].as_mut() {
*bucket += pairs[p].1;
} else {
buckets[nibble] = Some(pairs[p].1);
}
} }
} }
let mut intermediate_sum = G::identity(); let mut intermediate_sum = None;
for b in (1 .. buckets.len()).rev() { for b in (1 .. buckets.len()).rev() {
intermediate_sum += buckets[b]; if let Some(bucket) = buckets[b].as_ref() {
res += intermediate_sum; if let Some(intermediate_sum) = intermediate_sum.as_mut() {
*intermediate_sum += bucket;
} else {
intermediate_sum = Some(*bucket);
}
}
if let Some(intermediate_sum) = intermediate_sum.as_ref() {
res += intermediate_sum;
}
} }
} }

View file

@ -31,8 +31,10 @@ where
let mut res = G::identity(); let mut res = G::identity();
for b in (0 .. groupings[0].len()).rev() { for b in (0 .. groupings[0].len()).rev() {
for _ in 0 .. window { if b != (groupings[0].len() - 1) {
res = res.double(); for _ in 0 .. window {
res = res.double();
}
} }
for s in 0 .. tables.len() { for s in 0 .. tables.len() {
@ -51,20 +53,24 @@ where
let groupings = prep_bits(pairs, window); let groupings = prep_bits(pairs, window);
let tables = prep_tables(pairs, window); let tables = prep_tables(pairs, window);
let mut res = G::identity(); let mut res: Option<G> = None;
for b in (0 .. groupings[0].len()).rev() { for b in (0 .. groupings[0].len()).rev() {
if b != (groupings[0].len() - 1) { if b != (groupings[0].len() - 1) {
for _ in 0 .. window { for _ in 0 .. window {
res = res.double(); res = res.map(|res| res.double());
} }
} }
for s in 0 .. tables.len() { for s in 0 .. tables.len() {
if groupings[s][b] != 0 { if groupings[s][b] != 0 {
res += tables[s][usize::from(groupings[s][b])]; if let Some(res) = res.as_mut() {
*res += tables[s][usize::from(groupings[s][b])];
} else {
res = Some(tables[s][usize::from(groupings[s][b])]);
}
} }
} }
} }
res res.unwrap_or_else(G::identity)
} }