我正在用Rust为特定领域的语言编写解释器,该语言应允许高性能的实现。堆的相关属性为:
我在堆中的元素具有固定的结构:
pub enum Data {
Adt(u16, Vec<u64>),
Prim(Vec<u64>),
}
Vec<u64>
包含指向其他元素或原始数据的指针。
我首先考虑直接用枚举表示它。
这在运行时需要大量分配,并且需要Vec
的不必要的间接访问。还会浪费容量和大小字段的空间(因为数据是不可变的,并且大小是静态已知的)。
我对Rust还是比较陌生,并且使自己远离了不安全的代码,但是我认为这可能会有所帮助。我首先尝试表达我想要的功能:
#[derive(Copy, Clone)]
struct Data(u64);
struct DataStore(Vec<u64>);
impl DataStore {
fn alloc(max_size: u64) -> Self {
DataStore(Vec::with_capacity(max_size as usize))
}
fn new_adt(&mut self, tag: u16) -> Data {
let start = self.0.len() as u64;
let header = tag as u64;
self.0.push(header);
Data(start)
}
fn new_primitive(&mut self, data: &[u64]) -> Data {
let start = self.0.len() as u64;
for e in data {
self.0.push(*e)
}
Data(start)
}
fn init_adt_field(&mut self, Data(ptr): Data) {
self.0.push(ptr);
}
fn get_field(&self, Data(start): Data, index: u32) -> Data {
Data(self.0[(start + 1 + (index as u64)) as usize])
}
fn get_tag(&self, Data(start): Data) -> u16 {
self.0[start as usize] as u16
}
}
与Vec
相比,可以通过某种方式更有效地实现吗?我查看了TypedArena
,但不确定在这种情况下是否以及如何使用它。会比Vec
快吗? Vec
永远不会增长,因为它已初始化为具有静态证明足够的容量。
是否可以只分配一个内存Blob,然后使用不安全的指针?我在这里有什么选择?