2013-10-04 27 views
7

哪种方法更快,开销更少?清除矢量或定义一个新矢量,哪一个更快

方法1:

void foo() { 
    std::vector<int> aVector; 
    for (int i = 0; i < 1000000; ++i) { 
    aVector.clear(); 
    aVector.push_back(i); 
    } 
} 

方法2:

void foo() { 
    for (int i = 0; i < 1000000; ++i) { 
    std::vector<int> aVector; 
    aVector.push_back(i); 
    } 
} 

你可能会说的例子是没有意义的!但这只是我的大代码中的一小部分。总之我想知道的是它更好地

“创建矢量一次,清除它使用”

UPDATE

“每次创建新载体”

感谢您的建议,我测试了两个,这里是结果

方法1:

$ time ./test1 

real 0m0.044s 
user 0m0.042s 
sys  0m0.002s 

方法2:

$ time ./test2 

real 0m0.601s 
user 0m0.599s 
sys  0m0.002s 

清除矢量更好。也许这有助于其他人:)

+1

“清除矢量或定义一个新矢量,哪一个更快” - 基准它,你会知道的。没有可以做出的一般性陈述,因为这取决于许多平台和实现特定的细节。 – 2013-10-04 19:59:08

+0

同意,但我想知道g ++如何为方法生成优化的代码。哪一个更适合编译器? – mahmood

+2

如果有任何区别,我希望'clear'方法更快。 –

回答

6

clear()最有可能会更快,因为您将保留已分配给以前的push_back() s的内存到矢量中,从而减少了分配的需要。

此外,您还可以在每个循环中消除1个构造函数调用和1个析构函数调用。

这完全忽略了你的编译器优化器可能用这个代码做什么。

+0

+1这就是我要写的。 –

0

创建一个空矢量的开销很小。要将矢量增长到较大的尺寸可能相当昂贵,因为它每次都会增加一倍 - 所以1M条目矢量将具有由当前内容组成的15-20“副本”。

对于微不足道的基本类型,例如int,创建对象和销毁对象的开销是“无”,但对于任何更复杂的对象,您必须考虑对象的构造和销毁,这通常比“将对象放在矢量中”和“从矢量中移除它”要重要得多。换句话说,每个对象的构造函数和析构函数都是重要的。

对于每一个“X或Y更快”的情况,您确实需要为您想要了解的情况设定基准,除非它非常明显,其中一个明显快于另一个(例如“线性搜索或二进制搜索的X元素“,其中线性搜索与X成正比,二元搜索是log2(x))。

此外,我对你的例子有些困惑 - 在向量中存储ONE元素非常麻烦,并且在int x = i;之上存在一点点的开销 - 我认为你并不是真的将其作为基准。换句话说,你的特定比较不是很公平,因为清楚地构建1M个向量比构建一个向量更多的工作,并且填充它并且清除它1M次。但是,如果你让你的测试是这样的:

void foo() { 
    for (int i = 0; i < 1000; ++i) { 
    std::vector<int> aVector; 
    for(j = 0; j < 1000; j++) 
    { 
     aVector.push_back(i); 
    } 
    } 
} 

[和相应的换向等代码],我所期望的结果将是相当类似的。

+0

std :: vector动态分配内存。当动态分配例程被非常频繁地调用(如本例中)时,即使数据没有构造函数,它们也会变成大瓶颈。由于clear()通常不缩小内部数据,因此调用clear将会更快。 – SigTerm

+0

@SigTerm:是的,但你也可以使用'aVector.resize(1000)'来避免这种分配。但就像我说的,它取决于向量中存储的内容。 –

+0

如果目标是push_back元素,那么'aVector.reserve(1000)'会更准确。 –