From 63f80c0472c2f1449bbbcd0166b6ccd2e538f4a4 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Thu, 22 Oct 2020 12:53:12 +0200 Subject: [PATCH] perf: reduce allocations in AllocGadget::{alloc, alloc_input} Signed-off-by: ljedrz --- gadgets/src/signed_integer/utilities/alloc.rs | 67 +++++++++---------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/gadgets/src/signed_integer/utilities/alloc.rs b/gadgets/src/signed_integer/utilities/alloc.rs index 442abd7b6e..b47016a10b 100644 --- a/gadgets/src/signed_integer/utilities/alloc.rs +++ b/gadgets/src/signed_integer/utilities/alloc.rs @@ -16,7 +16,7 @@ use crate::{Int, Int128, Int16, Int32, Int64, Int8}; -use core::borrow::Borrow; +use core::{borrow::Borrow, iter}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ curves::Field, @@ -29,6 +29,21 @@ use snarkos_models::{ }, }; +fn create_value, I: IntoIterator>, F: Field, CS: ConstraintSystem>( + cs: &mut CS, + iter: I, +) -> Result, SynthesisError> { + iter.into_iter() + .enumerate() + .map(|(i, v)| { + Ok(Boolean::from(AllocatedBit::alloc( + &mut cs.ns(|| format!("allocated bit_gadget {}", i)), + || v.ok_or(SynthesisError::AssignmentMissing), + )?)) + }) + .collect() +} + macro_rules! alloc_int_impl { ($($gadget: ident)*) => ($( impl AllocGadget<<$gadget as Int>::IntegerType, F> for $gadget { @@ -41,30 +56,21 @@ macro_rules! alloc_int_impl { value_gen: Fn, ) -> Result { let value = value_gen().map(|val| *val.borrow()); - let values = match value { + + let bits = match value { Ok(mut val) => { let mut v = Vec::with_capacity(<$gadget as Int>::SIZE); - for _ in 0..<$gadget as Int>::SIZE { v.push(Some(val & 1 == 1)); val >>= 1; } - - v + create_value(&mut cs, v) } - _ => vec![None; <$gadget as Int>::SIZE], - }; - - let bits = values - .into_iter() - .enumerate() - .map(|(i, v)| { - Ok(Boolean::from(AllocatedBit::alloc( - &mut cs.ns(|| format!("allocated bit_gadget {}", i)), - || v.ok_or(SynthesisError::AssignmentMissing), - )?)) - }) - .collect::, SynthesisError>>()?; + Err(_) => { + let i = iter::repeat(None::).take(<$gadget as Int>::SIZE); + create_value(&mut cs, i) + }, + }?; Ok(Self { bits, @@ -81,30 +87,21 @@ macro_rules! alloc_int_impl { value_gen: Fn, ) -> Result { let value = value_gen().map(|val| *val.borrow()); - let values = match value { + + let bits = match value { Ok(mut val) => { let mut v = Vec::with_capacity(<$gadget as Int>::SIZE); - for _ in 0..<$gadget as Int>::SIZE { v.push(Some(val & 1 == 1)); val >>= 1; } - - v + create_value(&mut cs, v) } - _ => vec![None; <$gadget as Int>::SIZE], - }; - - let bits = values - .into_iter() - .enumerate() - .map(|(i, v)| { - Ok(Boolean::from(AllocatedBit::alloc( - &mut cs.ns(|| format!("allocated bit_gadget {}", i)), - || v.ok_or(SynthesisError::AssignmentMissing), - )?)) - }) - .collect::, SynthesisError>>()?; + Err(_) => { + let i = iter::repeat(None::).take(<$gadget as Int>::SIZE); + create_value(&mut cs, i) + }, + }?; Ok(Self { bits,