Created
December 25, 2024 22:32
-
-
Save dmitryvk/306f60e7e0f958a79435f75812ab36b6 to your computer and use it in GitHub Desktop.
Rust thread-local-storage microbenchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ptr::read_volatile; | |
pub const N_ITER: usize = 1000000000; | |
pub fn do_idle_read() -> i64 { | |
let mut r = 0; | |
for _ in 0..N_ITER { | |
r += do_idle_read_inner(); | |
} | |
r | |
} | |
#[inline(never)] | |
pub fn do_idle_read_inner() -> i64 { | |
1 | |
} | |
pub fn do_static_read() -> i64 { | |
let mut r = 0; | |
for _ in 0..N_ITER { | |
r += do_static_read_inner(); | |
} | |
r | |
} | |
#[inline(never)] | |
pub fn do_static_read_inner() -> i64 { | |
static VAR: i64 = 1; | |
unsafe { read_volatile(&raw const VAR) } | |
} | |
pub fn do_thread_static_read() -> i64 { | |
let mut r = 0; | |
for _ in 0..N_ITER { | |
r += do_thread_static_read_inner(); | |
} | |
r | |
} | |
#[inline(never)] | |
pub fn do_thread_static_read_inner() -> i64 { | |
thread_local! { | |
static VAR: i64 = const { 1 }; | |
} | |
VAR.with(|x| unsafe { read_volatile(&raw const *x) }) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::time::Instant; | |
fn main() { | |
// warmup | |
bin::do_idle_read(); | |
bin::do_static_read(); | |
bin::do_thread_static_read(); | |
try_thread_local::do_idle_read(); | |
try_thread_local::do_static_read(); | |
try_thread_local::do_thread_static_read(); | |
// bench_fn("bin::do_idle_read", bin::do_idle_read); | |
bench_fn("bin::do_static_read", bin::do_static_read); | |
bench_fn("bin::do_thread_static_read", bin::do_thread_static_read); | |
// bench_fn("lib::do_idle_read", try_thread_local::do_idle_read); | |
bench_fn("lib::do_static_read", try_thread_local::do_static_read); | |
bench_fn( | |
"lib::do_thread_static_read", | |
try_thread_local::do_thread_static_read, | |
); | |
} | |
fn bench_fn<F: FnOnce() -> i64>(name: &str, f: F) { | |
use try_thread_local::N_ITER; | |
let start = Instant::now(); | |
_ = f(); | |
let elapsed = start.elapsed(); | |
let nanos_per_iter = elapsed.as_nanos() as f64 / (N_ITER as f64); | |
println!("{name}: {nanos_per_iter:.2} ns/iter"); | |
} | |
#[path = "lib.rs"] | |
mod bin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment