-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Is your feature request related to a problem? Please describe.
No.
Describe the solution you'd like
Add a runtime builder option to turn off time-based metrics, and enable it by default to keep the same behavior as of now.
Describe alternatives you've considered
Feature gate to opt out of time based metrics? I think it too far though.
Additional context
I have encouter a noticeable performance regression and a flamegraph shows that the time based operation took up too much time. My scenario involves a lot of spawned tiny task and heavily relies on yield_now()
. Each task might run for hundreds of microseconds. And the timed-based metrics called Instant::now
and Instant::elapsed
for each task already takes up dozens of microseconds.
Here is a mininal MVP. Notice that only calling yield_now
already cause performance regression. I tested elapsed time between tokio 1.44.1 and 1.47.1, and the impact of time based metrics is quite obvious.
fn main() {
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
let now = std::time::Instant::now();
rt.block_on(async move {
for _ in 0..100_000_000 {
tokio::task::yield_now().await;
}
});
println!("Elapsed: {:?}", now.elapsed());
}
// tokio 1.44.1 Elapsed: 4.043231438s
// tokio 1.47.1 Elapsed: 11.043426378s
And the flamegraph on the tokio 1.47.1 version shows that time based operation is quite heavy, with Timespec::now
(the underlying syscall from Instant::now
) and Instant::elapsed
already took up 63% of the total flame. I think the gained observerbility is not worthy for a performance regression up to around 20% in my real world scrienario. And would like to find a way to turn off time based metrics.