You can use lazy-static to initialize the static array on first access, although it can incur minimal overhead (it seems to call Once :: call_once every time you access the static variable).
For example, Cargo.toml:
[package] name = "arr" version = "0.0.1" [[bin]] name = "arr" path = "arr.rs" [dependencies] lazy_static = "*"
arr.rs:
#[macro_use] extern crate lazy_static; use std::mem; use std::ptr; #[derive(Debug)] struct Mbuf { cacheline: *mut u64, } // Let pretend it thread-safe to appease the lazy_static! constrains. unsafe impl Sync for Mbuf { } lazy_static! { static ref ARR: [Mbuf; 32] = { let mut tmp: [Mbuf; 32] = unsafe { mem::uninitialized() }; for idx in 0..tmp.len() { tmp[idx] = Mbuf { cacheline: ptr::null_mut() }; } tmp }; } fn main() { println!("{:?}", *ARR); }
Alternatively, simply create your lazy accessory:
use std::mem; use std::ptr; #[derive(Debug)] struct Mbuf { cacheline: *mut u64, } static mut ARR: Option<[Mbuf; 32]> = None; fn arr() -> &'static mut [Mbuf; 32] { unsafe { if ARR.is_none() { let mut tmp: [Mbuf; 32] = mem::uninitialized(); for idx in 0..tmp.len() { tmp[idx] = Mbuf { cacheline: ptr::null_mut() }; } ARR = Some(tmp); } mem::transmute(ARR.as_mut().unwrap()) } } fn main() { println!("{:?}", arr()); }
Needless to say, this code is not thread safe and thus avoids some of Rust's security guarantees, but it will be sufficient for the speed comparison port.
source share