-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Timers currently use a BtreeMap which is theoretically efficient at scale, especially when there are thousands of timers, or when the thread is heavily overloaded. However a BtreeMap generates a lot of code, and is probably overkill. It would be better to have something tuned to this application. So these changes are proposed:
- New type
MonoTime(for monotonic time) which is time since baseInstantas au64in ns, allowing Stakker to run for 500+ years at a time. Support most things thatInstantdoes. Conversion to/fromInstantis supported via a Core reference to get the base time. Support creation directly from a time in ns to support virtual time without reference to anInstant - New type
MonoDurfor monotonic duration as au64in ns. Support easy conversion fromf64in seconds. Support most things thatDurationdoes, and conversion to/fromDuration - Switch all times and durations in API to use these types (or Into<...> these types), i.e. so Stakker can work purely with these types internally
- Create timer benchmarks (based on estimated realistic distribution of timers at various scales) and run against the current BtreeMap implementation
- Rewrite timer queue as a N-ary heap with an associated slab-style array to support deletion, and benchmark to check that this is an improvement
This will be a breaking API change, so it will mean going to 0.3. However API changes will be kept to a minimum and where code uses type inference it might not even notice. Justifications for design decisions:
Instantis problematic because the representation is different on different platforms, and calculations may be relatively heavy (e.g. macOS). Also, there's no way to construct anInstantzero. You always have to work relative to 'now' even if you're working in virtual time. Also secs/ns time inDurationis inconvenient to calculate with.- Using ns time is easy to calculate with (add/sub). Current Stakker timer code internally uses a compromise time representation with discontinuities.
- Converting secs/ns to ns is just a mul and add (fast).
- Converting back from ns to secs/ns (as used by Instant and Duration) requires a divide and modulus which is slow, but there shouldn't be much need to convert back within the Stakker system. Just maybe on the edges
- Encouraging const conversion of
f64toMonoDurmeans easy representation of durations in the code, which are converted to ns at compile-time - N-ary heap can be optimised to cache line size. It will produce a shallow tree. It should perform well for single timer fetches. It doesn't support partition to grab a whole chunk of timers like BtreeMap does. However the code will be many times smaller.
- Weak point of heap is O(N) deletion, which is worked around by having a slab-like vec associated with it where the callbacks are stored, where deletion can occur
nevercast
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request