Skip to content

Commit 0c833a8

Browse files
authored
Merge pull request #3166 from ProvableHQ/perf/bigint_cmp
[Perf] Optimize BigInteger comparisons
2 parents ac7daae + d4210ec commit 0c833a8

File tree

5 files changed

+93
-15
lines changed

5 files changed

+93
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utilities/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
2323
license = "Apache-2.0"
2424
edition = "2024"
2525

26+
[[bench]]
27+
name = "bigint"
28+
path = "benches/bigint.rs"
29+
harness = false
30+
2631
[dependencies.snarkvm-utilities-derives]
2732
workspace = true
2833
optional = true
@@ -78,6 +83,9 @@ default-features = false
7883
workspace = true
7984
features = [ "derive" ]
8085

86+
[dev-dependencies.criterion]
87+
workspace = true
88+
8189
[dev-dependencies.tracing-test]
8290
workspace = true
8391

utilities/benches/bigint.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) 2019-2026 Provable Inc.
2+
// This file is part of the snarkVM library.
3+
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at:
7+
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
// Silences the false positives caused by black_box.
17+
#![allow(clippy::unit_arg)]
18+
19+
use snarkvm_utilities::{BigInteger256, BigInteger384, TestRng};
20+
21+
use criterion::*;
22+
use rand::Rng;
23+
use std::hint::black_box;
24+
25+
fn bigint_256(c: &mut Criterion) {
26+
let rng = &mut TestRng::default();
27+
28+
let n = 900_000;
29+
let values: Vec<BigInteger256> = (0..n).map(|_| rng.r#gen()).collect();
30+
31+
c.bench_function("bigint_256_cmp", |b| {
32+
b.iter_batched(
33+
|| values.clone(),
34+
|mut data_to_sort| {
35+
data_to_sort.sort_unstable();
36+
black_box(data_to_sort)
37+
},
38+
criterion::BatchSize::LargeInput,
39+
)
40+
});
41+
}
42+
43+
fn bigint_384(c: &mut Criterion) {
44+
let rng = &mut TestRng::default();
45+
46+
let n = 500_000;
47+
let values: Vec<BigInteger384> = (0..n).map(|_| rng.r#gen()).collect();
48+
49+
c.bench_function("bigint_384_cmp", |b| {
50+
b.iter_batched(
51+
|| values.clone(),
52+
|mut data_to_sort| {
53+
data_to_sort.sort_unstable();
54+
black_box(data_to_sort)
55+
},
56+
criterion::BatchSize::LargeInput,
57+
)
58+
});
59+
}
60+
61+
criterion_group! {
62+
name = bigint;
63+
config = Criterion::default();
64+
targets = bigint_256, bigint_384
65+
}
66+
67+
criterion_main!(bigint);

utilities/src/biginteger/bigint_256.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16-
use std::io::{Read, Result as IoResult, Write};
16+
use std::{
17+
cmp,
18+
io::{Read, Result as IoResult, Write},
19+
};
1720

1821
use crate::{
1922
FromBits,
@@ -311,16 +314,15 @@ impl Display for BigInteger256 {
311314

312315
impl Ord for BigInteger256 {
313316
#[inline]
314-
#[allow(clippy::comparison_chain)]
315-
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
317+
fn cmp(&self, other: &Self) -> cmp::Ordering {
316318
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
317-
if a < b {
318-
return std::cmp::Ordering::Less;
319-
} else if a > b {
320-
return std::cmp::Ordering::Greater;
319+
match a.cmp(b) {
320+
cmp::Ordering::Less => return cmp::Ordering::Less,
321+
cmp::Ordering::Greater => return cmp::Ordering::Greater,
322+
_ => continue,
321323
}
322324
}
323-
std::cmp::Ordering::Equal
325+
cmp::Ordering::Equal
324326
}
325327
}
326328

utilities/src/biginteger/bigint_384.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// limitations under the License.
1515

1616
use std::{
17+
cmp,
1718
fmt::{Debug, Display},
1819
io::{Read, Result as IoResult, Write},
1920
};
@@ -309,16 +310,15 @@ impl Display for BigInteger384 {
309310
}
310311
impl Ord for BigInteger384 {
311312
#[inline]
312-
#[allow(clippy::comparison_chain)]
313-
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
313+
fn cmp(&self, other: &Self) -> cmp::Ordering {
314314
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
315-
if a < b {
316-
return std::cmp::Ordering::Less;
317-
} else if a > b {
318-
return std::cmp::Ordering::Greater;
315+
match a.cmp(b) {
316+
cmp::Ordering::Less => return cmp::Ordering::Less,
317+
cmp::Ordering::Greater => return cmp::Ordering::Greater,
318+
_ => continue,
319319
}
320320
}
321-
std::cmp::Ordering::Equal
321+
cmp::Ordering::Equal
322322
}
323323
}
324324
impl PartialOrd for BigInteger384 {

0 commit comments

Comments
 (0)