-
Notifications
You must be signed in to change notification settings - Fork 844
tracing: significantly improve code generation at trace points #3398
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
Conversation
|
Test and clippy failures are pre-existing. But the test failure is a little alarming since it's in the area that I'm changing. Looking into it. |
|
I see the test bug. Someone regressed the test last year while cleaning up warnings. I will open a separate PR to fix this. |
1f6c9aa to
48ce86e
Compare
hds
left a comment
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.
Thank you for your PR!
Question on the naming. But otherwise this looks good.
`ValueSet`s contain both a `FieldSet` reference and a slice of (`&Field`, `Option<&dyn Value>`) pairs. In cases where `ValueSet`s are generated via documented interfaces (specifically, `tracing::event!` and other macros), the `Field` references are redundant, because the `ValueSet` contains a value slot for every field (either a value or `None`), in the correct order. As a result, the code generated by the macros is terrible--it must put a `Field` on the stack for each field--that's 32 bytes per field! This is a lot of work for apparently no purpose at runtime, and it can't be moved into a read-only data section since it's intermixed with dynamic data. Fix this by adding a variant of `ValueSet` that skips the `Field` references, knowing that it represents the full set of fields. Keep the old kind of `ValueSet`, too--it's still needed by `Span::record`, by old versions of crates, and potentially by third-party crates using undocumented methods such as `FieldSet::value_set`. In some adhoc tests on x86_64 Linux, this reduces the code size as follows: * One-field event: 258 bytes to 189 bytes, 25% reduction. * Five-field event: 638 bytes to 276 bytes, **57%** reduction. * In a larger project with lots of events, ~5% reduction in .text section.
|
I've rebased and fixed some conflicts introduced by #3382. |
hds
left a comment
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.
Thank you for this PR! It's a great idea!
ValueSets contain both aFieldSetreference and a slice of (&Field,Option<&dyn Value>) pairs. In cases whereValueSets are generated via documented interfaces (specifically,tracing::event!and other macros), theFieldreferences are redundant, because theValueSetcontains a value slot for every field (either a value orNone), in the correct order.As a result, the code generated by the macros is terrible--it must put a
Fieldon the stack for each field--that's 32 bytes per field! This is a lot of work for apparently no purpose at runtime, and it can't be moved into a read-only data section since it's intermixed with dynamic data.Fix this by adding a variant of
ValueSetthat skips theFieldreferences, knowing that it represents the full set of fields. Keep the old kind ofValueSet, too--it's still needed bySpan::record, by old versions of crates, and potentially by third-party crates using undocumented methods such asFieldSet::value_set.In some adhoc tests on x86_64 Linux, this reduces the code size as follows: