如何有效地将切片复制到 Rust VecDeque 中

bru*_*olf 5 deque slice rust

我正在以流方式处理字节输入,如下所示:

pub struct CharQueue<R: Read> {
    reader: R,
    deque: VecDeque<u8>,
    buf: [u8;1024],
}
Run Code Online (Sandbox Code Playgroud)
self.deque.reserve_exact(bytes_read);
for i in 0..bytes_read {
    self.deque.push_back(self.buf[i]);
}
Run Code Online (Sandbox Code Playgroud)

在分析中,它似乎VecDeque::cap()是运行时的主要贡献者。这是令人惊讶的,因为它除了返回一个变量(我猜还有分支)之外几乎什么都不做:

fn cap(&self) -> usize {
    if mem::size_of::<T>() == 0 {
        // For zero sized types, we are always at maximum capacity
        MAXIMUM_ZST_CAPACITY
    } else {
        self.buf.capacity()
    }
}
Run Code Online (Sandbox Code Playgroud)

所以它一定被调用了很多次(如果它在 inside 被调用push_back(),事后看来这很有意义)。

我想知道是否有一种方法可以将整个缓冲区一次性复制到队列中,因此容量只需检查并增加一次。.reserve_exact()跳过中间分配,但不跳过检查和增量。.append()是这样的,但我必须先消耗缓冲区才能将其转换为另一个 VecDeque,但我不想这样做,因为我想重新使用它。我真正想要的是这样的东西push_back_slice(),只需要一个切片,增加队列长度/执行任何所需的分配一次,然后将切片的每个元素直接复制到可用空间中,而不改变或消耗它。

有没有办法做到这一点?

ape*_*lla 5

VecDeque实现该Extend特征,允许您将迭代器中的所有项目添加到集合中,而无需执行重复的分配或检查。使用您的代码,应该如下所示:

self.deque.extend(bytes_read.iter().copied());
Run Code Online (Sandbox Code Playgroud)