将切片附加到向量的惯用方法是什么?
What's the idiomatic way to append a slice to a vector?
我有一片 &[u8]
,我想将它附加到 Vec<u8>
中,并尽量减少复制。以下是我知道有效的两种方法:
let s = [0u8, 1u8, 2u8];
let mut v = Vec::new();
v.extend(s.iter().map(|&i| i));
v.extend(s.to_vec().into_iter()); // allocates an extra copy of the slice
在 Rust stable 中有更好的方法吗? (rustc 1.0.0-beta.2
)
v.extend(s.iter().cloned());
这实际上等同于使用 .map(|&i| i)
,并且它执行 最小 复制。
问题是在这种情况下你绝对不能避免复制。您不能简单地移动值,因为切片 不拥有其内容 ,因此它只能获取一个副本。
也就是说,有两件事需要考虑:
Rust 倾向于相当积极地内联;这段代码中有足够的信息供编译器直接将值复制到目标中而无需任何中间步骤。
Rust 中的闭包与大多数其他语言中的闭包不同:它们不需要堆分配并且可以直接内联,因此它们的效率不亚于直接对行为进行硬编码。
请记住,以上两项取决于优化:它们通常会达到最佳效果,但不能保证。
但是话虽如此...您在此 特定 示例中实际上想做的是附加一个堆栈-您 拥有的已分配数组。我不知道有任何库代码可以实际利用这一事实(目前 Rust 对数组值的支持相当薄弱),但理论上,您可以使用不安全代码有效地创建一个 into_iter()
等价物。 .. 但我不推荐它,它可能不值得麻烦。
我不能说出完整的性能影响,但 v + &s
将在测试版上运行,我认为这类似于将每个值推入原始 Vec。
有一种方法可以做到这一点:Vec::extend_from_slice
示例:
let s = [0u8, 1, 2];
let mut v = Vec::new();
v.extend_from_slice(&s);
我有一片 &[u8]
,我想将它附加到 Vec<u8>
中,并尽量减少复制。以下是我知道有效的两种方法:
let s = [0u8, 1u8, 2u8];
let mut v = Vec::new();
v.extend(s.iter().map(|&i| i));
v.extend(s.to_vec().into_iter()); // allocates an extra copy of the slice
在 Rust stable 中有更好的方法吗? (rustc 1.0.0-beta.2
)
v.extend(s.iter().cloned());
这实际上等同于使用 .map(|&i| i)
,并且它执行 最小 复制。
问题是在这种情况下你绝对不能避免复制。您不能简单地移动值,因为切片 不拥有其内容 ,因此它只能获取一个副本。
也就是说,有两件事需要考虑:
Rust 倾向于相当积极地内联;这段代码中有足够的信息供编译器直接将值复制到目标中而无需任何中间步骤。
Rust 中的闭包与大多数其他语言中的闭包不同:它们不需要堆分配并且可以直接内联,因此它们的效率不亚于直接对行为进行硬编码。
请记住,以上两项取决于优化:它们通常会达到最佳效果,但不能保证。
但是话虽如此...您在此 特定 示例中实际上想做的是附加一个堆栈-您 拥有的已分配数组。我不知道有任何库代码可以实际利用这一事实(目前 Rust 对数组值的支持相当薄弱),但理论上,您可以使用不安全代码有效地创建一个 into_iter()
等价物。 .. 但我不推荐它,它可能不值得麻烦。
我不能说出完整的性能影响,但 v + &s
将在测试版上运行,我认为这类似于将每个值推入原始 Vec。
有一种方法可以做到这一点:Vec::extend_from_slice
示例:
let s = [0u8, 1, 2];
let mut v = Vec::new();
v.extend_from_slice(&s);