Repository navigation
Serialize X-Ray and EMF request bodies directly - #374
Merged
Merged
Conversation
Both exporters built their request bodies by formatting serde_json::Value
trees through Display (which goes through a fmt::Write adapter), after
first copying already-formatted strings into new Values:
- X-Ray: each segment Value was formatted with to_string(), the strings
were copied into json!({"TraceSegmentDocuments": [...]}) and that Value
was formatted again.
- EMF: each EMF log line Value was formatted with to_string(), then every
event (timestamp + message) was copied into a json! object for the
PutLogEvents body, which was formatted again.
In profiles at saturation Value's Display impl was ~20% of CPU in both.
Use serde_json::to_string / to_vec, and serialize the request bodies from
small borrowing structs. Field order matches what the Value-based code
produced (serde_json objects are key-sorted), so the bodies are byte for
byte the same; tests compare against the previous construction.
Benchmark (rotel-bench, Intel N95, mock endpoints, 5+5 runs ABBA,
mean +- stddev, vs main):
EMF, 20k points/s: CPU/point -16.4% (10.8 -> 9.0 %/10k/s)
EMF, saturation (1 core): export requests/s 34.7 -> 45.3 (+30.7%),
CPU/point -24.6%
X-Ray, 50k spans/s: CPU/span -7.8% (11.0 -> 10.1 %/10k/s)
X-Ray, saturation: export requests/s 2,454 -> 2,840 (+15.7%),
client p99 363 -> 314 ms
(at saturation both exporters export slower than rotel ingests, so the
export rate is measured at the endpoint)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Both exporters built their request bodies by formatting serde_json::Value trees through Display (which goes through a fmt::Write adapter), after first copying already-formatted strings into new Values:
In profiles at saturation Value's Display impl was ~20% of CPU in both.
Use serde_json::to_string / to_vec, and serialize the request bodies from small borrowing structs. Field order matches what the Value-based code produced (serde_json objects are key-sorted), so the bodies are byte for byte the same; tests compare against the previous construction.
Benchmark (rotel-bench, Intel N95, mock endpoints, 5+5 runs ABBA, mean +- stddev, vs main):
EMF, 20k points/s: CPU/point -16.4% (10.8 -> 9.0 %/10k/s)
EMF, saturation (1 core): export requests/s 34.7 -> 45.3 (+30.7%),
CPU/point -24.6%
X-Ray, 50k spans/s: CPU/span -7.8% (11.0 -> 10.1 %/10k/s)
X-Ray, saturation: export requests/s 2,454 -> 2,840 (+15.7%),
client p99 363 -> 314 ms
(at saturation both exporters export slower than rotel ingests, so the
export rate is measured at the endpoint)