@ -1,20 +0,0 @@ |
|||
#[cfg(feature = "ark-bls12-377")]
|
|||
mod bls12_377;
|
|||
#[cfg(feature = "ark-bls12-381")]
|
|||
mod bls12_381;
|
|||
#[cfg(feature = "ark-bn254")]
|
|||
mod bn254;
|
|||
#[cfg(feature = "ark-bw6-761")]
|
|||
mod bw6_761;
|
|||
#[cfg(feature = "ark-cp6-782")]
|
|||
mod cp6_782;
|
|||
#[cfg(feature = "ark-ed-on-bls12-381")]
|
|||
mod ed_on_bls12_381;
|
|||
#[cfg(feature = "ark-mnt4-298")]
|
|||
mod mnt4_298;
|
|||
#[cfg(feature = "ark-mnt4-753")]
|
|||
mod mnt4_753;
|
|||
#[cfg(feature = "ark-mnt6-298")]
|
|||
mod mnt6_298;
|
|||
#[cfg(feature = "ark-mnt6-753")]
|
|||
mod mnt6_753;
|
@ -1,12 +1,13 @@ |
|||
#![cfg_attr(nightly, feature(test))]
|
|||
#![allow(unused_macros, unused_imports)]
|
|||
|
|||
#[cfg(nightly)]
|
|||
extern crate test;
|
|||
|
|||
#[cfg(all(nightly, test))]
|
|||
#[macro_use]
|
|||
pub mod macros;
|
|||
pub use macros::*;
|
|||
|
|||
#[cfg(all(nightly, test))]
|
|||
mod curves;
|
|||
#[cfg(feature = "criterion")]
|
|||
#[macro_use]
|
|||
pub extern crate criterion;
|
|||
pub use criterion::*;
|
|||
|
|||
#[macro_use]
|
|||
pub extern crate paste;
|
|||
pub use paste::*;
|
@ -1,405 +1,437 @@ |
|||
#[macro_export]
|
|||
macro_rules! f_bench {
|
|||
// Use this for base fields
|
|||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $field_ident:ident) => {
|
|||
field_common!($f, $f_type, $field_ident);
|
|||
sqrt!($f, $f_type, $field_ident);
|
|||
field_base!($f, $f_type, $f_repr, $f_repr_type, $field_ident);
|
|||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $modname:ident) => {
|
|||
$crate::paste!{
|
|||
pub mod [<_ $modname>] {
|
|||
use super::*;
|
|||
field_common!($f, $f_type);
|
|||
sqrt!($f, $f_type);
|
|||
prime_field!($f, $f_type, $f_repr, $f_repr_type);
|
|||
}
|
|||
$crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops, [<_ $modname>]::bench_sqrt, [<_ $modname>]::bench_prime_field_ops);
|
|||
}
|
|||
};
|
|||
// use this for intermediate fields
|
|||
(1, $f:ident, $f_type:ty, $field_ident:ident) => {
|
|||
field_common!($f, $f_type, $field_ident);
|
|||
sqrt!($f, $f_type, $field_ident);
|
|||
(extension, $f:ident, $f_type:ty, $modname:ident) => {
|
|||
$crate::paste!{
|
|||
mod [<_ $modname>] {
|
|||
use super::*;
|
|||
field_common!($f, $f_type);
|
|||
sqrt!($f, $f_type);
|
|||
}
|
|||
$crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops, [<_ $modname>]::bench_sqrt);
|
|||
}
|
|||
};
|
|||
// Use this for the full extension field Fqk
|
|||
(2, $f:ident, $f_type:ty, $field_ident:ident) => {
|
|||
field_common!($f, $f_type, $field_ident);
|
|||
(target, $f:ident, $f_type:ty, $modname:ident) => {
|
|||
crate::paste! {
|
|||
mod [<_ $modname>] {
|
|||
use super::*;
|
|||
field_common!($f, $f_type);
|
|||
}
|
|||
$crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops);
|
|||
}
|
|||
};
|
|||
}
|
|||
|
|||
#[macro_export]
|
|||
macro_rules! field_common {
|
|||
($f:ident, $f_type:ty, $field_ident:ident) => {
|
|||
paste::item! {
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _add_assign>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, add_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
($f:ident, $f_type:ty) => {
|
|||
pub fn bench_common_field_ops(c: &mut $crate::criterion::Criterion) {
|
|||
let mut group = c.benchmark_group("Common field operations for ".to_string() + core::stringify!($f));
|
|||
group.bench_function("AddAssign", add_assign);
|
|||
group.bench_function("SubAssign", sub_assign);
|
|||
group.bench_function("Double", double);
|
|||
group.bench_function("Negate", negate);
|
|||
group.bench_function("MulAssign", mul_assign);
|
|||
group.bench_function("Square", square);
|
|||
group.bench_function("Inverse", inverse);
|
|||
group.bench_function("Serialize w/ compression", ser);
|
|||
group.bench_function("Deserialize w/ compression", deser);
|
|||
group.bench_function("Serialize unchecked", ser_unchecked);
|
|||
group.bench_function("Deserialize unchecked", deser_unchecked);
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _sub_assign>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn add_assign(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, sub_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, add_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _mul_assign>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
fn sub_assign(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, mul_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _double>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, sub_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
fn double(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, double_in_place);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _square>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, double_in_place);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
fn negate(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, square_in_place);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _inverse>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
tmp = -tmp;
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
fn mul_assign(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count].inverse();
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _deser>](b: &mut ::test::Bencher) {
|
|||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut num_bytes = 0;
|
|||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
let tmp = $f::rand(&mut rng);
|
|||
tmp.serialize(&mut bytes).unwrap();
|
|||
num_bytes = bytes.len();
|
|||
bytes
|
|||
}).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
let index = count * num_bytes;
|
|||
$f_type::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
|||
});
|
|||
}
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, mul_assign, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
fn square(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, square_in_place);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _ser>](b: &mut ::test::Bencher) {
|
|||
use ark_serialize::CanonicalSerialize;
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
fn inverse(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count].inverse();
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
|
|||
fn deser(b: &mut $crate::criterion::Bencher) {
|
|||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut num_bytes = 0;
|
|||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
let tmp = $f::rand(&mut rng);
|
|||
tmp.serialize(&mut bytes).unwrap();
|
|||
num_bytes = bytes.len();
|
|||
bytes
|
|||
}).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
let index = count * num_bytes;
|
|||
<$f_type>::deserialize(&v[index..(index + num_bytes)]).unwrap()
|
|||
});
|
|||
}
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count];
|
|||
count = (count + 1) % SAMPLES;
|
|||
bytes.clear();
|
|||
tmp.serialize(&mut bytes)
|
|||
|
|||
});
|
|||
}
|
|||
fn ser(b: &mut $crate::criterion::Bencher) {
|
|||
use ark_serialize::CanonicalSerialize;
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _deser_unchecked>](b: &mut ::test::Bencher) {
|
|||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut num_bytes = 0;
|
|||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
let tmp = $f::rand(&mut rng);
|
|||
tmp.serialize_unchecked(&mut bytes).unwrap();
|
|||
num_bytes = bytes.len();
|
|||
bytes
|
|||
}).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
let index = count * num_bytes;
|
|||
$f_type::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
|||
});
|
|||
}
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _ser_unchecked>](b: &mut ::test::Bencher) {
|
|||
use ark_serialize::CanonicalSerialize;
|
|||
const SAMPLES: usize = 1000;
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count];
|
|||
count = (count + 1) % SAMPLES;
|
|||
bytes.clear();
|
|||
tmp.serialize(&mut bytes)
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
});
|
|||
}
|
|||
|
|||
|
|||
fn deser_unchecked(b: &mut $crate::criterion::Bencher) {
|
|||
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let mut num_bytes = 0;
|
|||
let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
let tmp = $f::rand(&mut rng);
|
|||
tmp.serialize_unchecked(&mut bytes).unwrap();
|
|||
num_bytes = bytes.len();
|
|||
bytes
|
|||
}).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
let index = count * num_bytes;
|
|||
<$f_type>::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
|
|||
});
|
|||
}
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count];
|
|||
count = (count + 1) % SAMPLES;
|
|||
bytes.clear();
|
|||
tmp.serialize_unchecked(&mut bytes)
|
|||
|
|||
});
|
|||
}
|
|||
fn ser_unchecked(b: &mut $crate::criterion::Bencher) {
|
|||
use ark_serialize::CanonicalSerialize;
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let mut bytes = Vec::with_capacity(1000);
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count];
|
|||
count = (count + 1) % SAMPLES;
|
|||
bytes.clear();
|
|||
tmp.serialize_unchecked(&mut bytes)
|
|||
|
|||
});
|
|||
}
|
|||
};
|
|||
}
|
|||
}
|
|||
|
|||
#[macro_export]
|
|||
macro_rules! sqrt {
|
|||
($f:ident, $f_type:ty, $field_ident:ident) => {
|
|||
paste::item! {
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _sqrt>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let mut tmp = $f::rand(&mut rng);
|
|||
tmp.square_in_place();
|
|||
tmp
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
v[count].sqrt()
|
|||
});
|
|||
}
|
|||
}
|
|||
};
|
|||
}
|
|||
($f:ident, $f_type:ty) => {
|
|||
pub fn bench_sqrt(b: &mut $crate::criterion::Criterion) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
macro_rules! field_base {
|
|||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $field_ident:ident) => {
|
|||
paste::item! {
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _repr_add_nocarry>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let mut tmp1 = $f_repr::rand(&mut rng);
|
|||
let mut tmp2 = $f_repr::rand(&mut rng);
|
|||
// Shave a few bits off to avoid overflow.
|
|||
for _ in 0..3 {
|
|||
tmp1.div2();
|
|||
tmp2.div2();
|
|||
}
|
|||
(tmp1, tmp2)
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, add_nocarry, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _repr_sub_noborrow>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let tmp1 = $f_repr::rand(&mut rng);
|
|||
let mut tmp2 = tmp1;
|
|||
// Ensure tmp2 is smaller than tmp1.
|
|||
for _ in 0..10 {
|
|||
tmp2.div2();
|
|||
}
|
|||
(tmp1, tmp2)
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, sub_noborrow, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
let v: Vec<$f_type> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let mut tmp = $f::rand(&mut rng);
|
|||
tmp.square_in_place();
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _repr_num_bits>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.bench_function(
|
|||
core::concat!("Square-roots for ", core::stringify!($f)),
|
|||
|_| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
let _ = v[count].sqrt();
|
|||
});
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
#[macro_export]
|
|||
macro_rules! prime_field {
|
|||
($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty) => {
|
|||
pub fn bench_prime_field_ops(c: &mut $crate::criterion::Criterion) {
|
|||
let mut group = c.benchmark_group("Prime field operations for ".to_string() + core::stringify!($f));
|
|||
group.bench_function("AddNoCarry for BigInteger", repr_add_nocarry);
|
|||
group.bench_function("SubNoBorrow for BigInteger", repr_sub_noborrow);
|
|||
group.bench_function("NumBits for BigInteger", repr_num_bits);
|
|||
group.bench_function("MulBy2 for BigInteger", repr_mul2);
|
|||
group.bench_function("DivBy2 for BigInteger", repr_div2);
|
|||
group.bench_function("Into BigInteger", into_repr);
|
|||
group.bench_function("From BigInteger", from_repr);
|
|||
}
|
|||
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
fn repr_add_nocarry(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let mut tmp1 = $f_repr::rand(&mut rng);
|
|||
let mut tmp2 = $f_repr::rand(&mut rng);
|
|||
// Shave a few bits off to avoid overflow.
|
|||
for _ in 0..3 {
|
|||
tmp1.div2();
|
|||
tmp2.div2();
|
|||
}
|
|||
(tmp1, tmp2)
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, add_nocarry, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count].num_bits();
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
fn repr_sub_noborrow(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<_> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
let tmp1 = $f_repr::rand(&mut rng);
|
|||
let mut tmp2 = tmp1;
|
|||
// Ensure tmp2 is smaller than tmp1.
|
|||
for _ in 0..10 {
|
|||
tmp2.div2();
|
|||
}
|
|||
(tmp1, tmp2)
|
|||
})
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count].0;
|
|||
n_fold!(tmp, v, sub_noborrow, count);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp;
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _repr_mul2>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn repr_num_bits(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, mul2);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let tmp = v[count].num_bits();
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp;
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _repr_div2>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn repr_mul2(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, div2);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, mul2);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp;
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _negate>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn repr_div2(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
tmp = -tmp;
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
let mut tmp = v[count];
|
|||
n_fold!(tmp, div2);
|
|||
count = (count + 1) % SAMPLES;
|
|||
tmp;
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _into_repr>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn into_repr(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
v[count].into_repr()
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
v[count].into_repr();
|
|||
});
|
|||
}
|
|||
|
|||
#[bench]
|
|||
fn [<bench_ $field_ident _from_repr>](b: &mut ::test::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
fn from_repr(b: &mut $crate::criterion::Bencher) {
|
|||
const SAMPLES: usize = 1000;
|
|||
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|||
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES)
|
|||
.map(|_| $f::rand(&mut rng).into_repr())
|
|||
.collect();
|
|||
let v: Vec<$f_repr_type> = (0..SAMPLES)
|
|||
.map(|_| $f::rand(&mut rng).into_repr())
|
|||
.collect();
|
|||
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
$f::from(v[count])
|
|||
});
|
|||
}
|
|||
let mut count = 0;
|
|||
b.iter(|| {
|
|||
count = (count + 1) % SAMPLES;
|
|||
$f::from(v[count]);
|
|||
});
|
|||
}
|
|||
};
|
|||
}
|
|||
}
|
@ -1,49 +1,10 @@ |
|||
#[macro_export]
|
|||
macro_rules! n_fold {
|
|||
($tmp:ident, $v:ident, $func:ident, $count:ident) => {
|
|||
const ITERS: usize = 1000;
|
|||
|
|||
#[cfg(not(feature = "n_fold"))]
|
|||
$tmp.$func(&$v[$count].1);
|
|||
#[cfg(feature = "n_fold")]
|
|||
for _ in 0..ITERS {
|
|||
$tmp.$func(&$v[$count].1);
|
|||
}
|
|||
};
|
|||
|
|||
($tmp:ident, $func:ident) => {
|
|||
const ITERS: usize = 1000;
|
|||
|
|||
#[cfg(not(feature = "n_fold"))]
|
|||
$tmp.$func();
|
|||
#[cfg(feature = "n_fold")]
|
|||
for _ in 0..ITERS {
|
|||
$tmp.$func();
|
|||
}
|
|||
};
|
|||
}
|
|||
|
|||
macro_rules! prepared_v {
|
|||
($v:ident, $rng:ident) => {
|
|||
let $v: Vec<(G1Prepared<Parameters>, G2Prepared<Parameters>)> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
(
|
|||
G1Affine::from(G1::rand(&mut $rng)).into(),
|
|||
G2Affine::from(G2::rand(&mut $rng)).into(),
|
|||
)
|
|||
})
|
|||
.collect();
|
|||
};
|
|||
}
|
|||
|
|||
macro_rules! affine_v {
|
|||
($v:ident, $rng:ident) => {
|
|||
let $v: Vec<(G1Affine, G2Affine)> = (0..SAMPLES)
|
|||
.map(|_| {
|
|||
(
|
|||
G1Affine::from(G1::rand(&mut $rng)).into(),
|
|||
G2Affine::from(G2::rand(&mut $rng)).into(),
|
|||
)
|
|||
})
|
|||
.collect();
|
|||
};
|
|||
}
|