-
Notifications
You must be signed in to change notification settings - Fork 11
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
[profiling] Reduce copying and allocation in exporter #926
base: main
Are you sure you want to change the base?
Conversation
BenchmarksComparisonBenchmark execution time: 2025-03-14 21:26:48 Comparing candidate commit f85951f in PR branch Found 0 performance improvements and 1 performance regressions! Performance is the same for 51 metrics, 2 unstable metrics. scenario:redis/obfuscate_redis_string
CandidateCandidate benchmark detailsGroup 1
Group 2
Group 3
Group 4
Group 5
Group 6
Group 7
Group 8
Group 9
Group 10
Group 11
Group 12
Group 13
BaselineOmitted due to size. |
8945950
to
0a70e3e
Compare
0a70e3e
to
dfa6eb3
Compare
dfa6eb3
to
606d179
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #926 +/- ##
=======================================
Coverage 72.79% 72.79%
=======================================
Files 334 334
Lines 50916 50882 -34
=======================================
- Hits 37062 37041 -21
+ Misses 13854 13841 -13
🚀 New features to boost your workflow:
|
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.
Gave it a pass!
Overall I like this PR less about the copying/allocation reduction and more as I think it's very useful to have a direct link between the profile and the exporter. In the past for instance we've had to expose the ProfiledEndpointsStats
because it was not encoded in the pprof. With this change, we can trivially report more things (metrics? other info?) that also don't get encoded in the pprof.
pub struct EncodedProfile { | ||
start: Timespec, | ||
end: Timespec, | ||
buffer: ddcommon_ffi::Vec<u8>, | ||
endpoints_stats: Box<ProfiledEndpointsStats>, | ||
} |
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.
Hmmm removing this leaves us in a weird in-between state -- I did find it useful to have the start
/end
here because in some cases I relied on libdatadog's defaults.
Providing start/end time is currently optional on a number of our APIs, so I think if we remove them here I think it's worth going ahead and also make them non-optional on the other APIs -- particularly in ddog_prof_Profile_serialize
(make non-optional) and possibly in ddog_prof_Profile_reset
/ddog_prof_Profile_new
(remove them?).
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.
I'd (mildly) rather do that on another PR so we can figure out the API we want, and when to use the current time vs requiring a time be passed in.
profiling/src/exporter/mod.rs
Outdated
pub fn build( | ||
&self, | ||
start: DateTime<Utc>, | ||
end: DateTime<Utc>, | ||
profile: EncodedProfile, | ||
files_to_compress_and_export: &[File], | ||
files_to_export_unmodified: &[File], | ||
additional_tags: Option<&Vec<Tag>>, | ||
endpoint_counts: Option<&ProfiledEndpointsStats>, | ||
internal_metadata: Option<serde_json::Value>, | ||
info: Option<serde_json::Value>, | ||
) -> anyhow::Result<Request> { |
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.
Consider perhaps making profile
optional? In particular, that enables experimentation around e.g. if I don't want to send a profile, or want to post-process the profile before sending it. (It's not a very strong use-case, but making it optional seems quite simple, and it'll be so annoying to otherwise have to create "dummy" profiles just to get around this if it's not)
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.
It makes the code a bit uglier, since we have to handle option some places. LMK if you think its worth it
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-apple-darwin
aarch64-unknown-linux-gnu
i686-alpine-linux-musl
i686-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-apple-darwin
x86_64-unknown-linux-gnu
|
What does this PR do?
Passes the
EncodedProfile
as a Rust object, rather than forcing it through the C-FFI straw.Motivation
We ended up having to make a new
Vec
and copy the bytes from the pprof in, even though they were already there. This saves the allocation and copy (which can be several MB).Additional Notes
Anything else we should know when reviewing?
How to test the change?
Existing tests