替代thread_local的效率更高!和lazy_static?

问题描述

我当前正在使用thread_local!宏:

thread_local!(static FOO: RefCell<Foo> = RefCell::new(Foo::new()));

我只需要对FOO的不变引用-它是只读的。其目的是缓存昂贵的计算结果,以便该结果可以在程序的其余部分中的许多地方使用,而无需显式传递函数和方法调用的许多级别。

如果没有作者,Rust允许多个读者。

有没有一种方法可以在main()(或之前)的开头创建只读全局变量FOO,并从多个线程(对所有线程都在FOO之后生成)进行只读访问。初始化)?

我看过lazy_static,但是它的初始化很懒,这意味着需要进行运行时检查以查看它是否已经初始化。我正在寻找一种东西,它只能编译为一个内存地址(在使用该内存的代码中),该内存的内容在main()的开头(或之前)初始化,并且永不更改。

解决方法

这真的感觉是没有必要的,除非在绝对关键的性能关键情况下。

有些板条箱(例如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());
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...