-
Notifications
You must be signed in to change notification settings - Fork 721
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
subscriber: rewrite Registry to use static arrays #2230
Comments
I think it should be possible to use The backwards-compatible scheme uses a global The exact same API works to require pre-registration; panic if the extension type is not registered, as this is clear programmer error. Super roughly, the idea is to invert from AoS Registry:
spans: Pool<SpanDataInner>
extensions: RwLock<AnyMap![Pool<Option<_>>]>
..
SpanData:
data: PoolRef<SpanDataInner>
extensions: &RwLock<AnyMap![Pool<Option<_>>]>
SpanDataInner:
extensions: SmallMap<TypeId, usize>,
..
SpanData.insert(self, val: T):
ext = None
exts = self.extensions.read()
if exts.get(T) is None:
exts = self.extensions.write()
exts.insert(T, RwLock(Pool()))
exts = self.extensions.read()
ext = exts.get(T)
ix = ext.insert(Some(T))
self.data.extensions.insert(T, ix)
SpanData.get(self, T):
exts = self.extensions.read()
ext = exts.get(T)?
ix = self.data.extensions.get(T)?
ext.get(ix).as_ref() |
Yes, a scheme like what you're describing here has been on my TODO list for a while. I think I have a partially-finished branch making a change like this somewhere. |
@CAD97, if you're interested in working on that, I would love a PR, and I can try to find what I wrote a while ago as a starting point, if you'd like it? |
I'd be happy to take a stab at it if you can find your old diff (and maybe even if you can't) |
Oh no, the problem with this approach is that Also, we don't have a If it's possible to store either of
Then that storage to do the locking can be put into Alternatively, we could prove that extending Also, I don't think it's possible for outside crates to implement
And this means the only useful implementation of |
So this is where I got in a quick test; the |
Concept for a smaller incremental improvement(?): Currently (IIUC), the I'm going to see if this approach works sometime this week as well. Perhaps these boxes can even be free-list-pooled and moved into the extensions map (rather than coming as part of the span data), even if pooling the extensions directly didn't work out. |
I wouldn't rule out a breaking change, @CAD97—if the performance improvement is as good as I think that it might be, then I think we should seriously considering release a tracing-subscriber 0.4 (alongside some other changes that have been queued up). |
I definitely want to get an 0.4 out at some point, so if we can come up with a really solid implementation of this that requires a breaking change, I would happily cut an 0.4 release for it. |
I think there's a few other items that merit a breaking release: https://github.com/tokio-rs/tracing/milestone/11 |
I'll revive the branch and see what I can do to chase the lifetime errors out then 🙂 Also, https://twitter.com/mycoliza/status/1530356065610567686?s=20&t=q2_dwEk3_1GnWorF1F4pBg wants to get into a tracing-subscriber bump (in tracing-filter as CAD97/tracing-filter#13) to have |
Oh, sorry! I meant that the breakage would be in |
For context, the Bevy reports that they incur about 10μs per each span/event when profiling. |
Feature Request
Crates
Motivation
The typemap-based used by the Registry's to store extensions is a typemap that erases types, places them into a Box, and stores the box into a
HashMap
. While this makes it easy to get started with theRegistry
, this approach does have a noticeable overhead when used in contexts such as profiling (e.g., bevyengine/bevy#4892).Proposal
Instead of using a
HashMap
for extensions,Layer
types would be required to pre-declare extension types they'd be storing in the Registry and use arrays to store extensions, avoiding the boxing (and potentially, the HashMap lookup).Alternatives
Don't do this, but I think that the performance benefits of this are non-trivial.
(Sorry this issue is a bit short, I had to run and most of the implementation details will be discovered while creating this API.)
The text was updated successfully, but these errors were encountered: