Skip to content

subscriber: make Registry::enter/exit much faster (backport #1058) #1059

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

Merged
merged 1 commit into from
Oct 22, 2020

Conversation

hawkw
Copy link
Member

@hawkw hawkw commented Oct 21, 2020

This backports #1058 to v0.1.x. This was already approved on master.

Motivation

We've tried very hard to make sure that entering and exiting spans is
lightweight...in the tracing-core core machinery. Unfortunately, we
haven't done any benchmarking of how subscriber implementations actually
handle enter/exit events. It turns out that in tracing-subscriber's
Registry, there's actually significant overhead for entering a span:
calling span.enter() may take as long as 69 ns (on my machine).

Solution

I've written some microbenchmarks for entering and exiting enabled spans
using tracing-subscriber::fmt, comparing them with the overhead of
calling enter on an enabled span. Based on this, I've made some
performance improvements. These optimizations include:

  • Removing the HashSet that's used for tracking previously entered
    span IDs, in favor of linear search. Span stacks probably never deep
    enough for a hashmap to be faster than iterating over a couple of
    vec indices.
  • Preallocating the vec used for the span stack to hold at least 64
    elements. This means we'll never have a lag spike from reallocating,
    as I think it'll almost never be deeper than 64 IDs.
  • Only cloning/dropping an ID's ref count for the first ID in the stack.

This makes entering and exiting enabled spans significantly faster:
image

It would be nice to continue optimizing this, but this might be about
the best it gets given the other requirements that we're now making
assertions about.

Signed-off-by: Eliza Weisman [email protected]

Motivation

Solution

## Motivation

We've tried very hard to make sure that entering and exiting spans is
lightweight...in the `tracing-core` core machinery. Unfortunately, we
haven't done any benchmarking of how subscriber implementations actually
handle enter/exit events. It turns out that in `tracing-subscriber`'s
`Registry`, there's actually significant overhead for entering a span:
calling `span.enter()` may take as long as 69 ns (on my machine).

## Solution

I've written some microbenchmarks for entering and exiting enabled spans
using `tracing-subscriber::fmt`, comparing them with the overhead of
calling `enter` on an enabled span. Based on this, I've made some
performance improvements. These optimizations include:

- Removing the `HashSet` that's used for tracking previously entered
  span IDs, in favor of linear search. Span stacks probably never deep
  enough for a hashmap to be faster than iterating over a couple of
  vec indices.
- Preallocating the vec used for the span stack to hold at least 64
  elements. This means we'll never have a lag spike from reallocating,
  as I think it'll almost never be deeper than 64 IDs.
- Only cloning/dropping an ID's ref count for the _first_ ID in the stack.

This makes entering and exiting enabled spans significantly faster:
![image](https://user-images.githubusercontent.com/2796466/96798681-3fc85000-13b6-11eb-9e85-7602d918ee09.png)

It would be nice to continue optimizing this, but this might be about
the best it gets given the other requirements that we're now making
assertions about.

Signed-off-by: Eliza Weisman <[email protected]>
@hawkw hawkw requested a review from a team as a code owner October 21, 2020 23:54
@hawkw hawkw merged commit 8406cbc into v0.1.x Oct 22, 2020
@jplatte jplatte deleted the eliza/backport-1058 branch June 3, 2025 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants