arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
ark-curves-cherry-picked/curve-benches/src/macros/field.rs
curve-benches/src/macros/field.rsRaw
  1#[macro_export]
  2macro_rules! f_bench {
  3    // Use this for base fields
  4    ($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty, $modname:ident) => {
  5        $crate::paste!{
  6            pub mod [<_ $modname>] {
  7                use super::*;
  8                field_common!($f, $f_type);
  9                sqrt!($f, $f_type);
 10                prime_field!($f, $f_type, $f_repr, $f_repr_type);
 11            }
 12            $crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops, [<_ $modname>]::bench_sqrt, [<_ $modname>]::bench_prime_field_ops);
 13        }
 14    };
 15    // use this for intermediate fields
 16    (extension, $f:ident, $f_type:ty, $modname:ident) => {
 17        $crate::paste!{
 18            mod [<_ $modname>] {
 19                use super::*;
 20                field_common!($f, $f_type);
 21                sqrt!($f, $f_type);
 22            }
 23            $crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops, [<_ $modname>]::bench_sqrt);
 24        }
 25    };
 26    // Use this for the full extension field Fqk
 27    (target, $f:ident, $f_type:ty, $modname:ident) => {
 28        crate::paste! {
 29            mod [<_ $modname>] {
 30                use super::*;
 31                field_common!($f, $f_type);
 32            }
 33            $crate::criterion::criterion_group!($modname, [<_ $modname>]::bench_common_field_ops);
 34        }
 35    };
 36}
 37
 38#[macro_export]
 39macro_rules! field_common {
 40    ($f:ident, $f_type:ty) => {
 41        pub fn bench_common_field_ops(c: &mut $crate::criterion::Criterion) {
 42            let mut group = c.benchmark_group("Common field operations for ".to_string() + core::stringify!($f));
 43            group.bench_function("AddAssign", add_assign);
 44            group.bench_function("SubAssign", sub_assign);
 45            group.bench_function("Double", double);
 46            group.bench_function("Negate", negate);
 47            group.bench_function("MulAssign", mul_assign);
 48            group.bench_function("Square", square);
 49            group.bench_function("Inverse", inverse);
 50            group.bench_function("Serialize w/ compression", ser);
 51            group.bench_function("Deserialize w/ compression", deser);
 52            group.bench_function("Serialize unchecked", ser_unchecked);
 53            group.bench_function("Deserialize unchecked", deser_unchecked);
 54        }
 55
 56        fn add_assign(b: &mut $crate::criterion::Bencher) {
 57            const SAMPLES: usize = 1000;
 58
 59            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
 60
 61            let v: Vec<_> = (0..SAMPLES)
 62                .map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
 63                .collect();
 64
 65            let mut count = 0;
 66            b.iter(|| {
 67                let mut tmp = v[count].0;
 68                n_fold!(tmp, v, add_assign, count);
 69                count = (count + 1) % SAMPLES;
 70                tmp
 71            });
 72        }
 73
 74
 75        fn sub_assign(b: &mut $crate::criterion::Bencher) {
 76            const SAMPLES: usize = 1000;
 77
 78            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
 79
 80            let v: Vec<_> = (0..SAMPLES)
 81                .map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
 82                .collect();
 83
 84            let mut count = 0;
 85            b.iter(|| {
 86                let mut tmp = v[count].0;
 87                n_fold!(tmp, v, sub_assign, count);
 88                count = (count + 1) % SAMPLES;
 89                tmp
 90            });
 91        }
 92
 93        fn double(b: &mut $crate::criterion::Bencher) {
 94            const SAMPLES: usize = 1000;
 95
 96            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
 97
 98            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
 99
100            let mut count = 0;
101            b.iter(|| {
102                let mut tmp = v[count];
103                n_fold!(tmp, double_in_place);
104                count = (count + 1) % SAMPLES;
105                tmp
106            });
107        }
108
109
110        fn negate(b: &mut $crate::criterion::Bencher) {
111            const SAMPLES: usize = 1000;
112
113            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
114
115            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
116
117            let mut count = 0;
118            b.iter(|| {
119                let mut tmp = v[count];
120                tmp = -tmp;
121                count = (count + 1) % SAMPLES;
122                tmp
123            });
124        }
125
126        fn mul_assign(b: &mut $crate::criterion::Bencher) {
127            const SAMPLES: usize = 1000;
128
129            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
130
131            let v: Vec<_> = (0..SAMPLES)
132                .map(|_| ($f::rand(&mut rng), $f::rand(&mut rng)))
133                .collect();
134
135            let mut count = 0;
136            b.iter(|| {
137                let mut tmp = v[count].0;
138                n_fold!(tmp, v, mul_assign, count);
139                count = (count + 1) % SAMPLES;
140                tmp
141            });
142        }
143
144        fn square(b: &mut $crate::criterion::Bencher) {
145            const SAMPLES: usize = 1000;
146
147            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
148
149            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
150
151            let mut count = 0;
152            b.iter(|| {
153                let mut tmp = v[count];
154                n_fold!(tmp, square_in_place);
155                count = (count + 1) % SAMPLES;
156                tmp
157            });
158        }
159
160
161        fn inverse(b: &mut $crate::criterion::Bencher) {
162            const SAMPLES: usize = 1000;
163
164            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
165
166            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
167
168            let mut count = 0;
169            b.iter(|| {
170                let tmp = v[count].inverse();
171                count = (count + 1) % SAMPLES;
172                tmp
173            });
174        }
175
176
177        fn deser(b: &mut $crate::criterion::Bencher) {
178            use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
179            const SAMPLES: usize = 1000;
180
181            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
182
183            let mut num_bytes = 0;
184            let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
185                let mut bytes = Vec::with_capacity(1000);
186                let tmp = $f::rand(&mut rng);
187                tmp.serialize(&mut bytes).unwrap();
188                num_bytes = bytes.len();
189                bytes
190            }).collect();
191
192            let mut count = 0;
193            b.iter(|| {
194                count = (count + 1) % SAMPLES;
195                let index = count * num_bytes;
196                <$f_type>::deserialize(&v[index..(index + num_bytes)]).unwrap()
197            });
198        }
199
200
201        fn ser(b: &mut $crate::criterion::Bencher) {
202            use ark_serialize::CanonicalSerialize;
203            const SAMPLES: usize = 1000;
204
205            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
206
207            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
208            let mut bytes = Vec::with_capacity(1000);
209
210            let mut count = 0;
211            b.iter(|| {
212                let tmp = v[count];
213                count = (count + 1) % SAMPLES;
214                bytes.clear();
215                tmp.serialize(&mut bytes)
216
217            });
218        }
219
220
221        fn deser_unchecked(b: &mut $crate::criterion::Bencher) {
222            use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
223            const SAMPLES: usize = 1000;
224
225            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
226
227            let mut num_bytes = 0;
228            let v: Vec<_> = (0..SAMPLES).flat_map(|_| {
229                let mut bytes = Vec::with_capacity(1000);
230                let tmp = $f::rand(&mut rng);
231                tmp.serialize_unchecked(&mut bytes).unwrap();
232                num_bytes = bytes.len();
233                bytes
234            }).collect();
235
236            let mut count = 0;
237            b.iter(|| {
238                count = (count + 1) % SAMPLES;
239                let index = count * num_bytes;
240                <$f_type>::deserialize_unchecked(&v[index..(index + num_bytes)]).unwrap()
241            });
242        }
243
244
245        fn ser_unchecked(b: &mut $crate::criterion::Bencher) {
246            use ark_serialize::CanonicalSerialize;
247            const SAMPLES: usize = 1000;
248
249            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
250
251            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
252            let mut bytes = Vec::with_capacity(1000);
253
254            let mut count = 0;
255            b.iter(|| {
256                let tmp = v[count];
257                count = (count + 1) % SAMPLES;
258                bytes.clear();
259                tmp.serialize_unchecked(&mut bytes)
260
261            });
262        }
263    }
264}
265
266#[macro_export]
267macro_rules! sqrt {
268    ($f:ident, $f_type:ty) => {
269        pub fn bench_sqrt(b: &mut $crate::criterion::Criterion) {
270            const SAMPLES: usize = 1000;
271
272            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
273
274            let v: Vec<$f_type> = (0..SAMPLES)
275                .map(|_| {
276                    let mut tmp = $f::rand(&mut rng);
277                    tmp.square_in_place();
278                    tmp
279                })
280            .collect();
281
282            let mut count = 0;
283            b.bench_function(
284                core::concat!("Square-roots for ", core::stringify!($f)),
285                |_| {
286                count = (count + 1) % SAMPLES;
287                let _ = v[count].sqrt();
288            });
289        }
290    }
291}
292
293#[macro_export]
294macro_rules! prime_field {
295    ($f:ident, $f_type:ty, $f_repr:ident, $f_repr_type:ty) => {
296        pub fn bench_prime_field_ops(c: &mut $crate::criterion::Criterion) {
297            let mut group = c.benchmark_group("Prime field operations for ".to_string() + core::stringify!($f));
298            group.bench_function("AddNoCarry for BigInteger", repr_add_nocarry);
299            group.bench_function("SubNoBorrow for BigInteger", repr_sub_noborrow);
300            group.bench_function("NumBits for BigInteger", repr_num_bits);
301            group.bench_function("MulBy2 for BigInteger", repr_mul2);
302            group.bench_function("DivBy2 for BigInteger", repr_div2);
303            group.bench_function("Into BigInteger", into_repr);
304            group.bench_function("From BigInteger", from_repr);
305        }
306
307        fn repr_add_nocarry(b: &mut $crate::criterion::Bencher) {
308            const SAMPLES: usize = 1000;
309
310            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
311
312            let v: Vec<_> = (0..SAMPLES)
313                .map(|_| {
314                    let mut tmp1 = $f_repr::rand(&mut rng);
315                    let mut tmp2 = $f_repr::rand(&mut rng);
316                    // Shave a few bits off to avoid overflow.
317                    for _ in 0..3 {
318                        tmp1.div2();
319                        tmp2.div2();
320                    }
321                    (tmp1, tmp2)
322                })
323            .collect();
324
325            let mut count = 0;
326            b.iter(|| {
327                let mut tmp = v[count].0;
328                n_fold!(tmp, v, add_nocarry, count);
329                count = (count + 1) % SAMPLES;
330                tmp
331            });
332        }
333
334        fn repr_sub_noborrow(b: &mut $crate::criterion::Bencher) {
335            const SAMPLES: usize = 1000;
336
337            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
338
339            let v: Vec<_> = (0..SAMPLES)
340                .map(|_| {
341                    let tmp1 = $f_repr::rand(&mut rng);
342                    let mut tmp2 = tmp1;
343                    // Ensure tmp2 is smaller than tmp1.
344                    for _ in 0..10 {
345                        tmp2.div2();
346                    }
347                    (tmp1, tmp2)
348                })
349            .collect();
350
351            let mut count = 0;
352            b.iter(|| {
353                let mut tmp = v[count].0;
354                n_fold!(tmp, v, sub_noborrow, count);
355                count = (count + 1) % SAMPLES;
356                tmp;
357            });
358        }
359
360        fn repr_num_bits(b: &mut $crate::criterion::Bencher) {
361            const SAMPLES: usize = 1000;
362
363            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
364
365            let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
366
367            let mut count = 0;
368            b.iter(|| {
369                let tmp = v[count].num_bits();
370                count = (count + 1) % SAMPLES;
371                tmp;
372            });
373        }
374
375        fn repr_mul2(b: &mut $crate::criterion::Bencher) {
376            const SAMPLES: usize = 1000;
377
378            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
379
380            let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
381
382            let mut count = 0;
383            b.iter(|| {
384                let mut tmp = v[count];
385                n_fold!(tmp, mul2);
386                count = (count + 1) % SAMPLES;
387                tmp;
388            });
389        }
390
391        fn repr_div2(b: &mut $crate::criterion::Bencher) {
392            const SAMPLES: usize = 1000;
393
394            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
395
396            let v: Vec<$f_repr_type> = (0..SAMPLES).map(|_| $f_repr::rand(&mut rng)).collect();
397
398            let mut count = 0;
399            b.iter(|| {
400                let mut tmp = v[count];
401                n_fold!(tmp, div2);
402                count = (count + 1) % SAMPLES;
403                tmp;
404            });
405        }
406
407        fn into_repr(b: &mut $crate::criterion::Bencher) {
408            const SAMPLES: usize = 1000;
409
410            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
411
412            let v: Vec<$f_type> = (0..SAMPLES).map(|_| $f::rand(&mut rng)).collect();
413
414            let mut count = 0;
415            b.iter(|| {
416                count = (count + 1) % SAMPLES;
417                v[count].into_repr();
418            });
419        }
420
421        fn from_repr(b: &mut $crate::criterion::Bencher) {
422            const SAMPLES: usize = 1000;
423
424            let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
425
426            let v: Vec<$f_repr_type> = (0..SAMPLES)
427                .map(|_| $f::rand(&mut rng).into_repr())
428                .collect();
429
430            let mut count = 0;
431            b.iter(|| {
432                count = (count + 1) % SAMPLES;
433                $f::from(v[count]);
434            });
435        }
436    }
437}