"cut and paste" std::vector 的最后 k 个元素是否有效?
"cut and paste" the last k elements of std::vector efficiently?
在 C++11 中是否有可能 "cut and paste" 一个 std::vector A 的最后 k 个元素在常数时间内到一个新的 std:::vector B?
一种方法是使用 B.insert(A.end() - k, A.end())
然后在 A 上使用擦除,但这都是 O(k) 时间操作。
茂
不,向量拥有自己的内存。
此操作称为拼接。 forward_list
在其他方面慢得离谱,但它确实有一个 O(1) 拼接。
通常,决定移动哪些元素的过程已经是 O(n),因此让拼接本身花费 O(n) 的时间不是问题。 vector 上的其他操作速度更快,足以弥补它。
这通常是不可能的,因为(至少在 C++03 版本中——它是 23.2.4/1)C++ 标准保证 vector<T>
使用的内存是一个连续的块。因此,在 O(1) 时间内 "transfer" 超过固定数量的元素的唯一方法是,如果接收向量为空,并且您以某种方式安排它的分配内存块从正确的位置开始 inside 第一个向量——在这种情况下,"transfer" 可以说根本没有花费时间。 (以这种方式故意重叠对象在理论上几乎肯定会构成未定义的行为——在实践中,它也非常脆弱,因为任何使迭代器无效到 vector<T>
的操作也可以重新分配内存,从而破坏事物。)
如果你准备牺牲一大堆可移植性,我听说可以玩 OS 级(或硬件级)虚拟内存映射技巧来实现诸如不-开销环形缓冲区。也许这些技巧也可以在这里应用——但请记住,虚拟内存到物理内存在单个进程中的映射是一对一的假设是根深蒂固的,所以你可能会遇到一些惊喜。
在 C++11 中是否有可能 "cut and paste" 一个 std::vector A 的最后 k 个元素在常数时间内到一个新的 std:::vector B?
一种方法是使用 B.insert(A.end() - k, A.end())
然后在 A 上使用擦除,但这都是 O(k) 时间操作。
茂
不,向量拥有自己的内存。
此操作称为拼接。 forward_list
在其他方面慢得离谱,但它确实有一个 O(1) 拼接。
通常,决定移动哪些元素的过程已经是 O(n),因此让拼接本身花费 O(n) 的时间不是问题。 vector 上的其他操作速度更快,足以弥补它。
这通常是不可能的,因为(至少在 C++03 版本中——它是 23.2.4/1)C++ 标准保证 vector<T>
使用的内存是一个连续的块。因此,在 O(1) 时间内 "transfer" 超过固定数量的元素的唯一方法是,如果接收向量为空,并且您以某种方式安排它的分配内存块从正确的位置开始 inside 第一个向量——在这种情况下,"transfer" 可以说根本没有花费时间。 (以这种方式故意重叠对象在理论上几乎肯定会构成未定义的行为——在实践中,它也非常脆弱,因为任何使迭代器无效到 vector<T>
的操作也可以重新分配内存,从而破坏事物。)
如果你准备牺牲一大堆可移植性,我听说可以玩 OS 级(或硬件级)虚拟内存映射技巧来实现诸如不-开销环形缓冲区。也许这些技巧也可以在这里应用——但请记住,虚拟内存到物理内存在单个进程中的映射是一对一的假设是根深蒂固的,所以你可能会遇到一些惊喜。