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 allocs when parsing Program #5

Open
wants to merge 2 commits into
base: mainnet-staging
Choose a base branch
from
Open
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions console/network/environment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,10 @@ pub mod prelude {
bytes::{complete::tag, streaming::take},
character::complete::{alpha1, alphanumeric1, char, one_of},
combinator::{complete, fail, map, map_res, opt, recognize},
error::{make_error, ErrorKind},
multi::{count, many0, many0_count, many1, separated_list0, separated_list1},
sequence::{pair, terminated},
Err,
};
pub use num_traits::{AsPrimitive, One, Pow, Zero};
pub use rand::{
Expand Down
2 changes: 0 additions & 2 deletions console/program/src/data_types/record_type/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ impl<N: Network> Parser for RecordType<N> {
Ok((string, (identifier, value_type)))
}

// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;
// Parse the type name from the string.
let (string, _) = tag(Self::type_name())(string)?;
// Parse the whitespace from the string.
Expand Down
2 changes: 0 additions & 2 deletions console/program/src/data_types/struct_type/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ impl<N: Network> Parser for StructType<N> {
Ok((string, (identifier, plaintext_type)))
}

// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;
// Parse the type name from the string.
let (string, _) = tag(Self::type_name())(string)?;
// Parse the whitespace from the string.
Expand Down
2 changes: 0 additions & 2 deletions synthesizer/program/src/closure/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ impl<N: Network, Instruction: InstructionTrait<N>> Parser for ClosureCore<N, Ins
/// Parses a string into a closure.
#[inline]
fn parse(string: &str) -> ParserResult<Self> {
// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;
// Parse the 'closure' keyword from the string.
let (string, _) = tag(Self::type_name())(string)?;
// Parse the whitespace from the string.
Expand Down
2 changes: 0 additions & 2 deletions synthesizer/program/src/function/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ impl<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>> Par
/// Parses a string into a function.
#[inline]
fn parse(string: &str) -> ParserResult<Self> {
// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;
// Parse the 'function' keyword from the string.
let (string, _) = tag(Self::type_name())(string)?;
// Parse the whitespace from the string.
Expand Down
4 changes: 3 additions & 1 deletion synthesizer/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ mod serialize;

use console::{
network::prelude::{
alt,
anyhow,
bail,
de,
ensure,
error,
fmt,
make_error,
many0,
many1,
map,
Expand All @@ -65,7 +65,9 @@ use console::{
Deserialize,
Deserializer,
Display,
Err,
Error,
ErrorKind,
Formatter,
FromBytes,
FromBytesDeserializer,
Expand Down
2 changes: 0 additions & 2 deletions synthesizer/program/src/mapping/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ impl<N: Network> Parser for Mapping<N> {
/// Parses a string into a mapping.
#[inline]
fn parse(string: &str) -> ParserResult<Self> {
// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;
// Parse the 'mapping' keyword from the string.
let (string, _) = tag(Self::type_name())(string)?;
// Parse the whitespace from the string.
Expand Down
96 changes: 54 additions & 42 deletions synthesizer/program/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,58 +44,70 @@ impl<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>> Par
// Parse the semicolon ';' keyword from the string.
let (string, _) = tag(";")(string)?;

fn intermediate<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>>(
string: &str,
) -> ParserResult<P<N, Instruction, Command>> {
// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;

if string.starts_with(Mapping::<N>::type_name()) {
map(Mapping::parse, |mapping| P::<N, Instruction, Command>::M(mapping))(string)
} else if string.starts_with(StructType::<N>::type_name()) {
map(StructType::parse, |struct_| P::<N, Instruction, Command>::I(struct_))(string)
} else if string.starts_with(RecordType::<N>::type_name()) {
map(RecordType::parse, |record| P::<N, Instruction, Command>::R(record))(string)
} else if string.starts_with(ClosureCore::<N, Instruction>::type_name()) {
map(ClosureCore::parse, |closure| P::<N, Instruction, Command>::C(closure))(string)
} else if string.starts_with(FunctionCore::<N, Instruction, Command>::type_name()) {
map(FunctionCore::parse, |function| P::<N, Instruction, Command>::F(function))(string)
} else {
Err(Err::Error(make_error(string, ErrorKind::Alt)))
}
}

// Parse the struct or function from the string.
let (string, components) = many1(alt((
map(Mapping::parse, |mapping| P::<N, Instruction, Command>::M(mapping)),
map(StructType::parse, |struct_| P::<N, Instruction, Command>::I(struct_)),
map(RecordType::parse, |record| P::<N, Instruction, Command>::R(record)),
map(ClosureCore::parse, |closure| P::<N, Instruction, Command>::C(closure)),
map(FunctionCore::parse, |function| P::<N, Instruction, Command>::F(function)),
)))(string)?;
let (string, components) = many1(intermediate)(string)?;
// Parse the whitespace and comments from the string.
let (string, _) = Sanitizer::parse(string)?;

// Return the program.
map_res(take(0usize), move |_| {
// Initialize a new program.
let mut program = match ProgramCore::<N, Instruction, Command>::new(id) {
Ok(program) => program,
// Initialize a new program.
let mut program = match ProgramCore::<N, Instruction, Command>::new(id) {
Ok(program) => program,
Err(error) => {
eprintln!("{error}");
return map_res(take(0usize), move |error| Err(error))(string);
}
};
// Construct the program with the parsed components.
for component in components {
let result = match component {
P::M(mapping) => program.add_mapping(mapping),
P::I(struct_) => program.add_struct(struct_),
P::R(record) => program.add_record(record),
P::C(closure) => program.add_closure(closure),
P::F(function) => program.add_function(function),
};

match result {
Ok(_) => (),
Err(error) => {
eprintln!("{error}");
return Err(error);
}
};
// Construct the program with the parsed components.
for component in components.iter() {
let result = match component {
P::M(mapping) => program.add_mapping(mapping.clone()),
P::I(struct_) => program.add_struct(struct_.clone()),
P::R(record) => program.add_record(record.clone()),
P::C(closure) => program.add_closure(closure.clone()),
P::F(function) => program.add_function(function.clone()),
};

match result {
Ok(_) => (),
Err(error) => {
eprintln!("{error}");
return Err(error);
}
return map_res(take(0usize), move |error| Err(error))(string);
}
}
// Lastly, add the imports (if any) to the program.
for import in imports.iter() {
match program.add_import(import.clone()) {
Ok(_) => (),
Err(error) => {
eprintln!("{error}");
return Err(error);
}
}
// Lastly, add the imports (if any) to the program.
for import in imports {
match program.add_import(import) {
Ok(_) => (),
Err(error) => {
eprintln!("{error}");
return map_res(take(0usize), move |error| Err(error))(string);
}
}
// Output the program.
Ok::<_, Error>(program)
})(string)
}

Ok((string, program))
}
}

Expand Down