-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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: optimize trace identifiers #5680
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best reviewed with "Hide whitespace"
impl LocalTraceIdentifier { | ||
pub fn new(known_contracts: &ContractsByArtifact) -> Self { | ||
Self { | ||
local_contracts: known_contracts | ||
.iter() | ||
.map(|(id, (abi, runtime_code))| (runtime_code.clone(), (id.clone(), abi.clone()))) | ||
.collect(), | ||
} | ||
impl<'a> LocalTraceIdentifier<'a> { | ||
pub fn new(known_contracts: &'a ContractsByArtifact) -> Self { | ||
Self { known_contracts } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove useless re-allocations, we only need to be able to iterate over the 3 values (id, abi, code)
TraceKind::Setup => { | ||
(verbosity == 4 && result.status.is_failure()) || verbosity >= 5 | ||
} | ||
TraceKind::Deployment => false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this exhaustive and a bit clearer
crates/forge/bin/cmd/test/mod.rs
Outdated
if should_include || gas_reporting { | ||
decoder.identify(trace, &mut local_identifier); | ||
decoder.identify(trace, &mut etherscan_identifier); | ||
decoder.decode(trace).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the main change, moved the identify
calls from above the match to inside the if block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change is really weird, it speeds up significantly when there are a lot of traces, but not when there are little? I don't really know or have the resources to investigate, so I'll remove it from this PR
Needs a fix, i would've made it a draft if i knew how to on mobile |
@DaniPopes gotcha, reopened and marked it as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love this. the changes here make sense
@@ -79,7 +79,7 @@ pub(crate) fn decode_cheatcode_inputs( | |||
"serializeBytes32" | | |||
"serializeString" | | |||
"serializeBytes" => { | |||
if verbosity == 5 { | |||
if verbosity >= 5 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch!
Motivation
Identifying and decoding traces contributes the majority (usually >40%) of the time spent in running tests. We can avoid most of this by just using the existing check flags to skip identifying only when needed.My assumptions were wrong. Generally, we decode traces on the main thread in parallel to the threads executing tests. This is a problem when there are a lot of them, and are sent batched (like for invariants). This causes the main thread to block for a while just decoding traces, which may also block after all tests are done.
This PR cleans up some tracing code, but the issue mentioned above will have to be fixed in another PR.
Solution