展平收片效率

Efficiency of flattening and collecting slices

如果在 Iterator<Item=&[T]> where T: Copy 上使用标准 .flatten().collect::<Box<[T]>>(),是否:

还是它做了一些效率较低的事情?

Box<[T]> 没有实现 FromIterator<&T>,所以我假设你的实际内部迭代器是产生拥有的 Ts.

的东西

FromIterator<T> for Box<[T]> forwards to Vec<T>, which uses size_hint()lower + 1 项目保留 space,并在超出该项目时重新分配(根据需要移动元素).所以问题是,Flatten<I> return 对于 size_hint 是什么?

Iterator::size_hint 的实施 Flatten<I> forwards to the internal struct FlattenCompat<I>, which is a little complicated because it supports double-ended iteration, but ultimately returns (0, None) if the outer iterator has not been advanced or exhausted

所以你的问题的答案是:它做了一些效率较低的事情。即,(除非您已经在迭代器上至少调用过 nextnext_back 一次)它会创建一个空的 Vec<T> 并根据 Vec 使用的任何增长策略逐步增长它(未指定,但 guaranteed by the documentation to result in O(1) amortized push)。

这不是人为限制;它是 Flatten 工作方式的基础。预先计算展平迭代器大小的唯一方法是用尽外部迭代器并将所有内部 size_hint 相加。这是一个坏主意,因为它并不总是有效(内部迭代器可能 return 没有用 size_hints),而且你还必须找到一种方法来在耗尽外面的;没有通用迭代器适配器可接受的解决方案。

如果您对特定迭代器有所了解,可以知道最终大小应该是多少,您可以通过调用 Vec::with_capacity 自己保留分配并使用 Extendflattened 迭代器,而不是使用 collect.