thread_local 的更有效替代方案! lazy_static?
More efficient alternative to thread_local! and lazy_static?
我目前正在使用 thread_local!
宏:
thread_local!(static FOO: RefCell<Foo> = RefCell::new(Foo::new()));
我只需要对 FOO 的不可变引用 - 它是只读的。它的目的是缓存昂贵计算的结果,以便该结果可以在程序其余部分的许多地方使用,而无需显式地通过许多级别的函数和方法调用。
如果没有写入器,Rust 允许多个读取器。
有没有一种方法可以让我在 main()
开始时(或之前)创建一个只读全局变量 FOO 并从多个线程(它们都在之后生成)获得对它的只读访问权限FOO 已初始化)?
我查看了 lazy_static
,但它具有惰性初始化,这意味着存在运行时检查以查看它是否已被初始化。我正在寻找仅编译为内存地址(在使用它的代码中)的东西,其中该内存的内容在 main()
开始时(或之前)初始化并且永远不会改变。
除了在绝对罕见的 performance-critical 情况下,这真的感觉没有必要。
有板条箱(例如 ctor
)可以让您在 main
之前进行计算,但是大多数 std
不能在 main
之前使用,所以您将你能做的事极其有限。如果我们要这样做,那么让我们把它作为 main
:
中的第一件事
// result of expensive calculation
#[derive(Debug)]
pub struct Foo(String);
static mut FOO: *const Foo = std::ptr::null();
fn init_foo() {
// expensive calculation
let foo = Box::new(Foo(String::from("expensive!")));
unsafe {
// leak the value, so it will never be dropped or freed
FOO = Box::leak(foo) as *const Foo;
}
}
// public accessor for Foo
pub fn get_foo() -> &'static Foo {
unsafe {
&*FOO
}
}
fn main() {
// better remember to do this or it's UB!
init_foo();
println!("foo = {:?}", get_foo());
}
我目前正在使用 thread_local!
宏:
thread_local!(static FOO: RefCell<Foo> = RefCell::new(Foo::new()));
我只需要对 FOO 的不可变引用 - 它是只读的。它的目的是缓存昂贵计算的结果,以便该结果可以在程序其余部分的许多地方使用,而无需显式地通过许多级别的函数和方法调用。
如果没有写入器,Rust 允许多个读取器。
有没有一种方法可以让我在 main()
开始时(或之前)创建一个只读全局变量 FOO 并从多个线程(它们都在之后生成)获得对它的只读访问权限FOO 已初始化)?
我查看了 lazy_static
,但它具有惰性初始化,这意味着存在运行时检查以查看它是否已被初始化。我正在寻找仅编译为内存地址(在使用它的代码中)的东西,其中该内存的内容在 main()
开始时(或之前)初始化并且永远不会改变。
除了在绝对罕见的 performance-critical 情况下,这真的感觉没有必要。
有板条箱(例如 ctor
)可以让您在 main
之前进行计算,但是大多数 std
不能在 main
之前使用,所以您将你能做的事极其有限。如果我们要这样做,那么让我们把它作为 main
:
// result of expensive calculation
#[derive(Debug)]
pub struct Foo(String);
static mut FOO: *const Foo = std::ptr::null();
fn init_foo() {
// expensive calculation
let foo = Box::new(Foo(String::from("expensive!")));
unsafe {
// leak the value, so it will never be dropped or freed
FOO = Box::leak(foo) as *const Foo;
}
}
// public accessor for Foo
pub fn get_foo() -> &'static Foo {
unsafe {
&*FOO
}
}
fn main() {
// better remember to do this or it's UB!
init_foo();
println!("foo = {:?}", get_foo());
}