可以比使用向量更有效地实现解释器堆吗?

时间:2018-07-11 18:29:29

标签: memory-management rust interpreter unsafe

我正在用Rust为特定领域的语言编写解释器,该语言应允许高性能的实现。堆的相关属性为:

  1. 程序简短(但很多程序都已执行)
  2. 我知道在执行开始之前,需要的最大内存量
  3. 所需的内存很小
  4. 在程序终止之前不需要取消分配
  5. 创建后所有数据都是不可变的
  6. 该语言经过静态类型检查,因此没有访问未初始化内存的风险
  7. 语言为单线程,因此没有共享内存

我在堆中的元素具有固定的结构:

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,然后使用不安全的指针?我在这里有什么选择?

0 个答案:

没有答案