Something went wrong. Try again.
🦀🚀 Abstract over `Send` and `!Send` traits crates.io/crates/future_form
Something went wrong. Try again.
future_form DESIGN.md
1.8 kB
Markdown
at fix-macro
Design Notes #
Performance Impact of Boxing Futures #
future_form uses BoxFuture and LocalBoxFuture under the hood. This section discusses the performance implications of that choice.
Costs #
Allocation
- One heap allocation per boxed future (typically small, but adds up in hot paths)
- Deallocation when the future completes
Indirection
- Virtual dispatch through the
dyn Futuretrait object on each poll - Pointer chasing can hurt CPU cache locality
In Practice #
The impact is often negligible because:
- Futures are usually polled relatively few times compared to the work they represent
- A single network call or disk read dwarfs the cost of one allocation
- The allocator is highly optimized for small, short-lived allocations
When It Matters #
- Tight loops spawning thousands of tiny futures
- Latency-critical code paths (microsecond-level)
- Embedded/
no_stdenvironments with constrained allocators
Alternatives #
| Approach | Tradeoff |
|---|---|
async-trait |
Same cost (also boxes) |
impl Future (static dispatch) |
Avoids boxing but can't be used in trait objects or with this kind of abstraction |
| Enum-based dispatch | Works for a fixed set of variants, but doesn't generalize |
Recommendation #
For most async code doing I/O, the boxing cost is noise. If profiling shows it's a bottleneck, you'd typically avoid the abstraction entirely in that hot path rather than try to optimize the boxing.