ark_algebra_bench_templates/macros/
ec.rs1#[macro_export]
2macro_rules! ec_bench {
3 ($curve_name:expr, $Group:ident) => {
4 $crate::paste! {
5 mod [<$Group:lower>] {
6 use ark_ec::PrimeGroup;
7 use super::*;
8
9 type Scalar = <$Group as PrimeGroup>::ScalarField;
10 fn rand(c: &mut $crate::criterion::Criterion) {
11 let name = format!("{}::{}", $curve_name, stringify!($Group));
12 use ark_std::UniformRand;
13 let mut rng = ark_std::test_rng();
14 c.bench_function(
15 &format!("Sample {name} elements"),
16 |b| b.iter(|| <$Group>::rand(&mut rng)),
17 );
18 }
19
20 fn arithmetic(c: &mut $crate::criterion::Criterion) {
21 use ark_ff::AdditiveGroup;
22 use ark_ec::{CurveGroup, PrimeGroup};
23 use ark_std::UniformRand;
24 let name = format!("{}::{}", $curve_name, stringify!($Group));
25
26 type Scalar = <$Group as PrimeGroup>::ScalarField;
27 const SAMPLES: usize = 1000;
28 let mut rng = ark_std::test_rng();
29 let mut arithmetic =
30 c.benchmark_group(format!("Arithmetic for {name}"));
31 let group_elements_left = (0..SAMPLES)
32 .map(|_| <$Group>::rand(&mut rng))
33 .collect::<Vec<_>>();
34 let group_elements_right = (0..SAMPLES)
35 .map(|_| <$Group>::rand(&mut rng))
36 .collect::<Vec<_>>();
37 let group_elements_right_affine = <$Group>::normalize_batch(&group_elements_right);
38 let scalars = (0..SAMPLES)
39 .map(|_| Scalar::rand(&mut rng))
40 .collect::<Vec<_>>();
41 arithmetic.bench_function("Addition", |b| {
42 let mut i = 0;
43 b.iter(|| {
44 i = (i + 1) % SAMPLES;
45 group_elements_left[i] + group_elements_right[i]
46 })
47 });
48 arithmetic.bench_function(
49 "Subtraction",
50 |b| {
51 let mut i = 0;
52 b.iter(|| {
53 i = (i + 1) % SAMPLES;
54 group_elements_left[i] - group_elements_right[i]
55 })
56 },
57 );
58
59 arithmetic.bench_function(
60 "Mixed Addition",
61 |b| {
62 let mut i = 0;
63 b.iter(|| {
64 i = (i + 1) % SAMPLES;
65 group_elements_left[i] + group_elements_right_affine[i]
66 })
67 },
68 );
69
70 arithmetic.bench_function(
71 "Mixed Subtraction",
72 |b| {
73 let mut i = 0;
74 b.iter(|| {
75 i = (i + 1) % SAMPLES;
76 group_elements_left[i] - group_elements_right_affine[i]
77 })
78 },
79 );
80
81 arithmetic.bench_function("Double", |b| {
82 let mut i = 0;
83 b.iter(|| {
84 i = (i + 1) % SAMPLES;
85 group_elements_left[i].double()
86 })
87 });
88
89 arithmetic.bench_function(
90 "Scalar Multiplication",
91 |b| {
92 let mut i = 0;
93 b.iter(|| {
94 i = (i + 1) % SAMPLES;
95 group_elements_left[i] * scalars[i]
96 })
97 },
98 );
99 }
100
101 fn serialization(c: &mut $crate::criterion::Criterion) {
102 use ark_ec::CurveGroup;
103 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
104 use ark_std::UniformRand;
105
106 const SAMPLES: usize = 1000;
107
108 let name = format!("{}::{}", $curve_name, stringify!($Group));
109 let mut rng = ark_std::test_rng();
110
111 let v: Vec<_> = (0..SAMPLES)
112 .map(|_| <$Group>::rand(&mut rng))
113 .collect();
114 let v = <$Group>::normalize_batch(&v);
115 let mut bytes = Vec::with_capacity(1000);
116 let v_compressed = v
117 .iter()
118 .map(|a| {
119 let mut bytes = Vec::with_capacity(1000);
120 a.serialize_compressed(&mut bytes).unwrap();
121 bytes
122 })
123 .collect::<Vec<_>>();
124 let v_uncompressed = v
125 .iter()
126 .map(|a| {
127 let mut bytes = Vec::with_capacity(1000);
128 a.serialize_uncompressed(&mut bytes).unwrap();
129 bytes
130 })
131 .collect::<Vec<_>>();
132 let mut serialization =
133 c.benchmark_group(format!("Serialization for {name}"));
134 serialization.bench_function(
135 "Serialize Compressed",
136 |b| {
137 let mut i = 0;
138 b.iter(|| {
139 i = (i + 1) % SAMPLES;
140 bytes.clear();
141 v[i].serialize_compressed(&mut bytes).unwrap()
142 })
143 },
144 );
145 serialization.bench_function(
146 "Serialize Uncompressed",
147 |b| {
148 let mut i = 0;
149 b.iter(|| {
150 i = (i + 1) % SAMPLES;
151 bytes.clear();
152 v[i].serialize_uncompressed(&mut bytes).unwrap()
153 })
154 },
155 );
156 serialization.bench_function(
157 "Deserialize Compressed",
158 |b| {
159 let mut i = 0;
160 b.iter(|| {
161 i = (i + 1) % SAMPLES;
162 bytes.clear();
163 <$Group>::deserialize_compressed(v_compressed[i].as_slice()).unwrap()
164 })
165 },
166 );
167 serialization.bench_function(
168 "Deserialize Compressed Unchecked",
169 |b| {
170 let mut i = 0;
171 b.iter(|| {
172 i = (i + 1) % SAMPLES;
173 bytes.clear();
174 <$Group>::deserialize_compressed_unchecked(v_compressed[i].as_slice())
175 .unwrap()
176 })
177 },
178 );
179 serialization.bench_function(
180 "Deserialize Uncompressed",
181 |b| {
182 let mut i = 0;
183 b.iter(|| {
184 i = (i + 1) % SAMPLES;
185 bytes.clear();
186 <$Group>::deserialize_uncompressed(v_uncompressed[i].as_slice())
187 .unwrap()
188 })
189 },
190 );
191 serialization.bench_function(
192 "Deserialize Uncompressed Unchecked",
193 |b| {
194 let mut i = 0;
195 b.iter(|| {
196 i = (i + 1) % SAMPLES;
197 bytes.clear();
198 <$Group>::deserialize_uncompressed_unchecked(
199 v_uncompressed[i].as_slice(),
200 )
201 .unwrap()
202 })
203 },
204 );
205 }
206
207 fn msm_131072(c: &mut $crate::criterion::Criterion) {
208 use ark_ec::{scalar_mul::variable_base::VariableBaseMSM, CurveGroup};
209 use ark_ff::PrimeField;
210 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
211 use ark_std::UniformRand;
212
213 const SAMPLES: usize = 131072;
214
215 let name = format!("{}::{}", $curve_name, stringify!($Group));
216 let mut rng = ark_std::test_rng();
217
218 let v: Vec<_> = (0..SAMPLES)
219 .map(|_| <$Group>::rand(&mut rng))
220 .collect();
221 let v = <$Group>::normalize_batch(&v);
222 let scalars: Vec<_> = (0..SAMPLES)
223 .map(|_| Scalar::rand(&mut rng).into_bigint())
224 .collect();
225 c.bench_function(&format!("MSM for {name}"), |b| {
226 b.iter(|| {
227 let result: $Group = VariableBaseMSM::msm_bigint(&v, &scalars);
228 result
229 })
230 });
231 }
232
233 $crate::criterion_group!(benches, rand, arithmetic, serialization, msm_131072,);
234 }
235 }
236 };
237}