C++ 在STD的中间删除一个元素::向量仍然用移动类型昂贵吗? 一般认为删除中间的元素STD::vector < /代码>是昂贵的,因为它需要在每个元素之后复制它来填充空洞。

C++ 在STD的中间删除一个元素::向量仍然用移动类型昂贵吗? 一般认为删除中间的元素STD::vector < /代码>是昂贵的,因为它需要在每个元素之后复制它来填充空洞。,c++,vector,c++11,move-semantics,C++,Vector,C++11,Move Semantics,使用C++11,std::vector会将所有元素下移,这应该非常快(如果只与副本相关),至少我认为是这样。当然,它在时间上仍然是线性的,但总的来说,它应该比旧版本快 这是真的吗?我不必担心在中间删除某个对象吗?< P>我仍然是C++ 0x移动的新手,但我真的看不出你在这里会得到什么有用的加速,这是代码< >向量< /代码>的固有的。 必须归结到元素类型:我无法想象你会得到任何加速,除非元素类型的对象移动比复制快。这取决于向量中的内容。如果它是一个豆荚或指针,我无法想象它会有什么不同。如果类实例

使用C++11,
std::vector
会将所有元素下移,这应该非常快(如果只与副本相关),至少我认为是这样。当然,它在时间上仍然是线性的,但总的来说,它应该比旧版本快


这是真的吗?我不必担心在中间删除某个对象吗?

< P>我仍然是C++ 0x移动的新手,但我真的看不出你在这里会得到什么有用的加速,这是代码< >向量< /代码>的固有的。


必须归结到元素类型:我无法想象你会得到任何加速,除非元素类型的对象移动比复制快。

这取决于向量中的内容。如果它是一个豆荚或指针,我无法想象它会有什么不同。如果类实例很难复制,但可以移动得很快,那么我希望C++0x能够加快速度


但是,我认为如果从std::vectors中间删除元素是代码中的一个瓶颈,那么C++0x可能不是正确的修复方法。考虑更好地处理这种情况的数据结构,或者“代码> STD::ItdioSwite STD::vector:POPYBACK/<代码>如果元素的顺序不重要。

< P>如果考虑到标准使用的成本,它将是完全一样昂贵的。该标准规定了在包含类型上执行操作的成本,并且操作的数量仍然相同,只是每个操作都会更快

作为例子,在C++ 03中考虑在元素< <代码>向量< /代码>中插入元素的成本。标准调用

O(N)
,其中
N
是向量的大小,但实际成本是
O(N*M)
,其中
M
是字符串的大小。在分析容器中的操作成本时忽略
M
的原因是它取决于所包含的元素。在C++0x中,使用可移动类型的代价将是
O(N)
(字符串可以移动到新位置),但在这两种情况下,公布的复杂性都将是
O(N)

一个简单的反例,如果你认为在向量中间插入是一个昂贵的C++ 03的操作,你考虑 STD::vector ,那么在C++中的向量中间插入同样昂贵,在这种情况下没有加速。


还要注意的是,任何潜在的改进都取决于对象的可移动性(它们不需要移动),并且当前的一些STL实现已经以类似的方式进行了优化(没有语言支持),例如,Dinkumware实现(我想就是这个)进行一些优化,当
std::vector
增长时,它会创建新的存储并使用空向量(没有分配的内存,因此成本最低)初始化,然后
交换新旧分配区域中的向量,有效地实现移动语义。

有效地,在绝大多数情况下,移动要比复制快得多。任何类型都可以通过引用存储信息,否则就必须复制这些信息,从而防止复制—例如,几乎所有容器、智能指针等,以及涉及这些类型的任何类


当然,这仍然是线性时间,所以如果你有一百万整数,它不会更快。然而,移动诸如容器和智能指针之类的东西可能比复制它们快几个数量级。

第一个即将决定需要向量或列表的点?如果您不希望基于索引访问数据结构,那么列表会很好,因为您的删除发生在容器的中间。此外,你必须考虑其他变种,如树木,以决定对你最好的。这可能不会对您的性能产生太大影响,但仍然只是为了共享信息,列表中的内容有可能分布在多个页面文件中,因此在使用大量数据时会影响性能


可以提高容器的性能。它可以避免一些不必要的复制操作等。

在C++03中不能交换对象吗?如果是这样的话,性能差异将非常小。@jalf:好吧,这就是
unee_erase
的工作原理-
swap
与last和
pop_back
,但是如果你想保持顺序,你不能只交换。@Xeo:同样的方法是从中间移除元素,然后移动一个元素到向量的末尾,您可以将要删除的元素与下一个元素交换,将其移动到向量的末尾,然后调用
pop_back
@jalf:据我所知,只有VC9在其STL中执行“交换优化”,因为容器不需要有效地容纳可交换的元素。@David:在您对@Xeo的回复中,您似乎描述了一种更复杂、更随意的方法来实现相同的目的?这基本上适用于几乎所有昂贵的类型。@DeadMG:是的,但是OP没有指定他的元素类型是否昂贵。如果不昂贵,则从中间删除也不昂贵,这是过早的优化。@DeadMG:如果向量较大,那么,即使复制/移动每个元素的成本很低,从中间删除也会很昂贵。@DeadMG:这里的过早优化是什么?如果所有的字符都包含少于16个字符,那么将移动语义引入C++字符串将不会更快地移动(而不是复制)。因为智能指针存储在原地。对于智能指针,您肯定是在谈论
共享\u ptr
,因为
唯一的
是不可复制的,所以它可以