标准库中不存在fn take<T>(vec: Vec<T>, index: usize) -> Option<T>
的原因,是它一般不是很有用。例如,假设你有一个长度为10的Vec<String>
,这意味着扔掉9个字符串,只使用1。这看起来很浪费。
通常,标准库将尝试提供在最大场景中有用的API,在这种情况下,拥有fn take<T>(vec: &mut Vec<T>, index: usize) -> Option<T>
会更合乎逻辑。
唯一的问题是如何保持不变,当然:
- 可以通过最后一个元素,这是什么
Vec::swap_remove
做交换被保留,
- 它可以通过改变被保留后继元素,这是
Vec::drain
做什么。
这些非常灵活,可以适应更多特定场景,比如你的。
适应swap_remove
:
fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
if index < vec.len() {
Some(vec.swap_remove(index))
} else {
None
}
}
适应drain
:
fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
if index < vec.len() {
vec.drain(index..index+1).next()
} else {
None
}
}
注意到,前者是更有效的:它的O(1)。
为了进一步澄清,我正在寻找消耗的Vec
,并返回一个元素的方法,无需恢复Vec
的不变量的方式remove
和swap_remove
做的开销。
这对我来说过早的微观优化。
首先,请注意,有必要销毁向量的元素;您可以通过两种方式实现:
swap_remove
,然后每个元素遍历消灭他们,
- 遍历每个元素来消灭它们,跳过特定
index
。
我不清楚后者会比前者快;如果有任何事情看起来更复杂,更多的分支(我建议两个循环),这可能会甩掉预测器,并且可能不太适合矢量化。
其次,在抱怨恢复Vec
的不变量的开销之前,你有没有正确的配置文件的解决方案?
如果我们看一下swap_remove
变型中,有3个步骤:
swap_remove
(O(1)),
- 破坏每个剩余元素(O(N)),
- 自由的后备记忆。
步骤2可以被优化了,如果元素没有Drop
实施,但除此之外,我会它是一个抛是否(2)或(3)占主导的成本。
TL; DR:恐怕你在拼鬼的问题,配置文件试图优化之前。
你是指''选项'而不是'选项<&T>',你可以从'vec.get(index)'得到,或者你错过'.get'存在吗? –
loganfsmyth
@loganfsmyth我特意指'选项'就像我在问题中说的那样。我想要的是类似于'option.take()'如果这是有道理的? –
Others
注意:如果您发现自己定期抛出“Vec”,则可能需要查看是否可以避免实现它们。不管做什么都比做某事快,无论你做得多高效。 –