Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Perf] Reduce allocations in ToBits for Plaintext #2458

Merged
merged 1 commit into from
May 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions circuit/program/src/data/plaintext/to_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Literal(literal, bits_le) => {
// Compute the bits of the literal.
let bits = bits_le.get_or_init(|| {
let mut bits_le = vec![Boolean::constant(false), Boolean::constant(false)]; // Variant bit.
let mut bits_le = Vec::new();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this is a conservative tweak which ensures that the vector starts out with a capacity larger than 2 elements

bits_le.extend([Boolean::constant(false), Boolean::constant(false)]); // Variant bit.
literal.variant().write_bits_le(&mut bits_le);
literal.size_in_bits().write_bits_le(&mut bits_le);
literal.write_bits_le(&mut bits_le);
bits_le.shrink_to_fit();
bits_le
});
// Extend the vector with the bits of the literal.
Expand All @@ -35,15 +37,17 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Struct(members, bits_le) => {
// Compute the bits of the struct.
let bits = bits_le.get_or_init(|| {
let mut bits_le = vec![Boolean::constant(false), Boolean::constant(true)]; // Variant bit.
let mut bits_le = Vec::new();
bits_le.extend([Boolean::constant(false), Boolean::constant(true)]); // Variant bit.
U8::constant(console::U8::new(members.len() as u8)).write_bits_le(&mut bits_le);
for (identifier, value) in members {
let value_bits = value.to_bits_le();
identifier.size_in_bits().write_bits_le(&mut bits_le);
identifier.write_bits_le(&mut bits_le);
U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_le(&mut bits_le);
bits_le.extend_from_slice(&value_bits);
bits_le.extend(value_bits);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Vec::extend is preferable here, as it avoids cloning the members of of value_bits.

}
bits_le.shrink_to_fit();
bits_le
});
// Extend the vector with the bits of the struct.
Expand All @@ -52,13 +56,15 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Array(elements, bits_le) => {
// Compute the bits of the array.
let bits = bits_le.get_or_init(|| {
let mut bits_le = vec![Boolean::constant(true), Boolean::constant(false)]; // Variant bit.
let mut bits_le = Vec::new();
bits_le.extend([Boolean::constant(true), Boolean::constant(false)]); // Variant bit.
U32::constant(console::U32::new(elements.len() as u32)).write_bits_le(&mut bits_le);
for value in elements {
let value_bits = value.to_bits_le();
U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_le(&mut bits_le);
bits_le.extend(value_bits);
}
bits_le.shrink_to_fit();
bits_le
});
// Extend the vector with the bits of the array.
Expand All @@ -73,10 +79,12 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Literal(literal, bits_be) => {
// Compute the bits of the literal.
let bits = bits_be.get_or_init(|| {
let mut bits_be = vec![Boolean::constant(false), Boolean::constant(false)]; // Variant bit.
let mut bits_be = Vec::new();
bits_be.extend([Boolean::constant(false), Boolean::constant(false)]); // Variant bit.
literal.variant().write_bits_be(&mut bits_be);
literal.size_in_bits().write_bits_be(&mut bits_be);
literal.write_bits_be(&mut bits_be);
bits_be.shrink_to_fit();
bits_be
});
// Extend the vector with the bits of the literal.
Expand All @@ -85,15 +93,17 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Struct(members, bits_be) => {
// Compute the bits of the struct.
let bits = bits_be.get_or_init(|| {
let mut bits_be = vec![Boolean::constant(false), Boolean::constant(true)]; // Variant bit.
let mut bits_be = Vec::new();
bits_be.extend([Boolean::constant(false), Boolean::constant(true)]); // Variant bit.
U8::constant(console::U8::new(members.len() as u8)).write_bits_be(&mut bits_be);
for (identifier, value) in members {
let value_bits = value.to_bits_be();
identifier.size_in_bits().write_bits_be(&mut bits_be);
identifier.write_bits_be(&mut bits_be);
U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_be(&mut bits_be);
bits_be.extend_from_slice(&value_bits);
bits_be.extend(value_bits);
}
bits_be.shrink_to_fit();
bits_be
});
// Extend the vector with the bits of the struct.
Expand All @@ -102,13 +112,15 @@ impl<A: Aleo> ToBits for Plaintext<A> {
Self::Array(elements, bits_be) => {
// Compute the bits of the array.
let bits = bits_be.get_or_init(|| {
let mut bits_be = vec![Boolean::constant(true), Boolean::constant(false)]; // Variant bit.
let mut bits_be = Vec::new();
bits_be.extend([Boolean::constant(true), Boolean::constant(false)]); // Variant bit.
U32::constant(console::U32::new(elements.len() as u32)).write_bits_be(&mut bits_be);
for value in elements {
let value_bits = value.to_bits_be();
U16::constant(console::U16::new(value_bits.len() as u16)).write_bits_be(&mut bits_be);
bits_be.extend(value_bits);
}
bits_be.shrink_to_fit();
bits_be
});
// Extend the vector with the bits of the array.
Expand Down