使用“Option”来可能分配?

huangapple go评论80阅读模式
英文:

Use `Option` to maybe allocate?

问题

这段代码是否会避免分配内存(基于某个运行时谓词)?或者 Option<Vec<T>> 是否总是会导致分配?

let mut x: Option<Vec<u32>> = None;
if predicate {
    x = Some(vec!(1,2,3));
}

另一方面,由于优化的原因,是否不需要使用 Option,因为空的 Vec 不会导致分配内存?

英文:

Does this code avoid allocation if it's not needed (based on some runtime predicate)? Or does Option<Vec<T>> always result in an allocation?

let mut x: Option<Vec<u32>> = None;
if predicate {
    x = Some(vec!(1,2,3));
}

On the other hand, is this use of Option unnecessary due to optimizations meaning empty Vecs don't result in allocations anyway?

答案1

得分: 9

在Rust中,Option<Vec<T>>只有在实际使用并包含一些元素时才会分配内存。当你声明一个类型为Option<Vec<T>>的变量并将其设置为None时,它不会为Vec分配内存。它只会消耗存储Option本身所需的内存,该内存有空间来存储None变体。只有当它被设置为Some(vec)时,它才会分配Vec所需的内存。

所以,回答你的第一个问题,你的代码中的Option<Vec<T>>在谓词为真且采用Some(vec![1, 2, 3])分支时才会分配内存。

对于你的第二个问题,一个空的Vec不会分配内存。在Rust中,Vec有一个容量(capacity),即为未来元素分配的空间量,还有一个长度(length),即实际元素的数量。如果创建一个Vec并没有向其中添加任何元素,它的长度为0,容量也是0,因此不会分配任何内存来存储元素。

因此,如果你确定在谓词为假时Vec将为空,你实际上可以使用一个空的Vec来避免不必要的内存分配。以下是如何做到的:

let mut x: Vec<u32> = Vec::new();
if predicate {
    x = vec![1,2,3];
}

这将只有在谓词为true时才为Vec分配内存。但从语义上讲,这与None和空向量不同。如果在你的上下文中,没有值(None)和一个空值(Vec::new())之间的区别很重要,那么你应该继续使用Option<Vec<T>>。否则,你可以直接使用Vec<T>

英文:

In Rust, an Option&lt;Vec&lt;T&gt;&gt; is not going to allocate memory until and unless it is actually used and contains some elements. When you declare a variable of type Option&lt;Vec&lt;T&gt;&gt; and set it to None, it does not allocate memory for the Vec. It only consumes the memory needed to store the Option itself, which has space for the None variant. When it's set to Some(vec), only then will it allocate the memory required for the Vec.

So, to answer your first question, the Option&lt;Vec&lt;T&gt;&gt; in your code will not allocate memory until the predicate is true and the Some(vec![1, 2, 3]) branch is taken.

For your second question, an empty Vec does not allocate. A Vec in Rust has a capacity, which is the amount of space allocated for any future elements, and a length, which is the number of actual elements. If you create a Vec and don't add any elements to it, its length is 0 and so is its capacity, and thus it doesn't allocate any memory for the elements.

So you can actually use an empty Vec to avoid unnecessary memory allocation if you are sure that your Vec will be empty when the predicate is false. Here's how you could do it,

let mut x: Vec&lt;u32&gt; = Vec::new();
if predicate {
    x = vec![1,2,3];
}

This will not allocate memory for the Vec until the predicate is true. But it is different semantically because None and an empty vector are not the same. If the distinction between no value (None) and an empty value (Vec::new()) is important in your context, you should keep using Option&lt;Vec&lt;T&gt;&gt; Otherwise, you can use Vec&lt;T&gt; directly.

答案2

得分: 2

The allocation is done in the code that the vec![<elements>] macro generates, so yes.

vec![<elements>]宏生成的代码中执行了分配,所以是的。

You can reduce allocations when you already know how much elements you will write to the vector with Vec::with_capacity().

如果您已经知道要向向量写入多少元素,可以使用Vec::with_capacity()来减少分配。

On the other hand, is this use of Option unnecessary due to optimizations meaning empty Vecs don't result in allocations anyway?

另一方面,由于优化的原因,使用Option是否不必要,因为空的Vec不会导致分配?

Source

英文:

The allocation is done in the code that the vec![&lt;elements&gt;] macro generates, so yes.

You can reduce allocations when you already know how much elements you will write to the vector with Vec::with_capacity()

> On the other hand, is this use of Option unnecessary due to optimizations meaning empty Vecs don't result in allocations anyway?

https://stackoverflow.com/questions/76171712/will-an-empty-vec-which-is-never-used-still-be-allocated

huangapple
  • 本文由 发表于 2023年8月5日 04:41:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定