【问题标题】:Is it possible to define the increment factor for reallocations to std::vec::Vec?是否可以定义重新分配到 std::vec::Vec 的增量因子?
【发布时间】:2019-05-29 16:58:41
【问题描述】:

我有一个缓慢增长的std::vec::Vec。对于超出其容量的向量的每次重新分配,我希望重新分配由静态数量的元素完成。

例如,我最初分配了一个包含 1024 个元素的向量。当它达到其容量时,我希望它重新分配 32 个元素,并且我希望这个参数是可配置的。

我正在寻找这样的功能:

Vec::new(initial_capacity, capacity_increment);

地点:

initial_capacity = 1024;
capacity_increment = 32;

Rust 中是否提供此功能(夜间或稳定)?

文档说您只能指定初始容量,但不清楚每次重新分配时如何增加大小或是否可以更改此参数。事实上,文档说Vec 将成为(pointer, capacity, length) 三元组不多也不少

有没有办法进行容量增量配置?

我需要这个功能,因为我可能在向量中有大量元素,并且每次重新分配少量额外容量都会导致我正在运行的进程出现相当大的延迟。

【问题讨论】:

  • 你能打电话给reserve_exact吗?
  • “我需要这个功能,因为我可能在向量中有大量元素,并且每次重新分配少量额外容量都会导致我正在运行的进程出现相当大的延迟。” ???看起来你在考虑只是在程序完成后对其进行基准测试,看看你是否有工作台问题。不要在 prod 中过度提交
  • Vec 使用的实际分配策略是每次将容量翻倍,因此您描述的行为听起来并不正确。您实际上是通过重复分配来衡量性能问题还是只是在猜测?
  • @PeterHall ,我试图弄清楚它如何增加容量,并让它像我需要的那样工作。尚未运行任何测试。

标签: rust


【解决方案1】:

不,Vec(从 Rust 1.35 开始)不提供任何控制重新分配策略的机制。

当您调用Vec::push 之类的方法时,current implementation of Vec 将在向量已满时将容量翻倍。当你调用像reserve_exact 这样的方法时,current implementation of Vec 直接使用你的容量。

文档说Vec 将成为(pointer, capacity, length) 三元组不多也不少

这并不排除以非常谨慎的方式扩展Vec 的可能性。例如,Vec 是从RawVec 构建的,即parameterized by an allocator。只要您使用零大小的分配器(例如Global),大小仍然是真实的。

在概念上直接使用另一个类型参数来控制调整大小的行为。话虽如此,这似乎不太可能很快发生。

解决方法

如果您真的需要这样的东西,您可以围绕Vec 创建一个新类型,并在所有适当的位置调用reserve_exact

struct MyVec<T> {
    v: Vec<T>,
    increment: usize,
}

impl<T> MyVec<T> {
    fn new(capacity: usize, increment: usize) -> MyVec<T> {
        MyVec {
            v: Vec::with_capacity(capacity),
            increment,
        }
    }

    fn push(&mut self, val: T) {
        if self.v.len() == self.v.capacity() {
            self.v.reserve_exact(self.increment);
        }
        self.v.push(val);
    }
}

免费咨询

在您获得以下基准之前,不要尝试优化它:

  1. 表明这是一个瓶颈
  2. 可用于证明您的“优化”实际上让事情变得更快

我的向量中可能有大量元素,每次重新分配少量额外容量都会导致我正在运行的进程出现相当大的延迟。

我同意这是一种直觉,这就是为什么你的想法让我如此困惑:

我希望它重新分配 32 个元素

32 个元素少量的额外容量;这样做似乎会降低性能。

【讨论】:

  • newtype 的问题是你必须委托每一个方法,以使其符合人体工程学 - 并为更多的方法进行检查和重新分配,而不是 push .只需实现 Deref&lt;Target = Vec&lt;T&gt;&gt; 即可“免费”获得其中一些方法,但它也有局限性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多