From fd00c834371674a8a51af3f19513c223754cdafa Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:34:08 +0200 Subject: [PATCH] perf: link in parallel --- crates/linking/Cargo.toml | 5 ++++- crates/linking/src/lib.rs | 17 +++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/linking/Cargo.toml b/crates/linking/Cargo.toml index 15d0d113b74d8..c30e4de0d8eec 100644 --- a/crates/linking/Cargo.toml +++ b/crates/linking/Cargo.toml @@ -15,6 +15,9 @@ workspace = true [dependencies] foundry-compilers = { workspace = true, features = ["full"] } -semver.workspace = true + alloy-primitives = { workspace = true, features = ["rlp"] } + +rayon.workspace = true +semver.workspace = true thiserror.workspace = true diff --git a/crates/linking/src/lib.rs b/crates/linking/src/lib.rs index 96e0664f22f54..1508ed31ff61c 100644 --- a/crates/linking/src/lib.rs +++ b/crates/linking/src/lib.rs @@ -11,6 +11,7 @@ use foundry_compilers::{ artifacts::{CompactContractBytecodeCow, Libraries}, contracts::ArtifactContracts, }; +use rayon::prelude::*; use semver::Version; use std::{ collections::{BTreeMap, BTreeSet}, @@ -174,7 +175,7 @@ impl<'a> Linker<'a> { // Link and collect bytecodes for `libs_to_deploy`. let libs_to_deploy = libs_to_deploy - .into_iter() + .into_par_iter() .map(|(id, _)| { Ok(self.link(id, &libraries)?.get_bytecode_bytes().unwrap().into_owned()) }) @@ -198,7 +199,7 @@ impl<'a> Linker<'a> { self.collect_dependencies(target, &mut needed_libraries)?; let mut needed_libraries = needed_libraries - .into_iter() + .into_par_iter() .filter(|id| { // Filter out already provided libraries. let (file, name) = self.convert_artifact_id_to_lib_path(id); @@ -233,9 +234,9 @@ impl<'a> Linker<'a> { let (file, name) = self.convert_artifact_id_to_lib_path(id); - for (_, bytecode) in &mut needed_libraries { + needed_libraries.par_iter_mut().for_each(|(_, bytecode)| { bytecode.to_mut().link(&file.to_string_lossy(), &name, address); - } + }); libraries.libs.entry(file).or_default().insert(name, address.to_checksum(None)); } @@ -295,14 +296,18 @@ impl<'a> Linker<'a> { &self, libraries: &Libraries, ) -> Result { - self.contracts.keys().map(|id| Ok((id.clone(), self.link(id, libraries)?))).collect() + self.get_linked_artifacts_cow(libraries).map(ArtifactContracts::from_iter) } pub fn get_linked_artifacts_cow( &self, libraries: &Libraries, ) -> Result>, LinkerError> { - self.contracts.keys().map(|id| Ok((id.clone(), self.link(id, libraries)?))).collect() + self.contracts + .par_iter() + .map(|(id, _)| Ok((id.clone(), self.link(id, libraries)?.into()))) + .collect::>() + .map(ArtifactContracts) } }