2011-09-08 49 views
6

我有一个关于在C++中std :: vector <>的性能的问题。通过调用clear()方法重用相同的矢量还是快速重新创建矢量更快?更快:重新创建或清除()?

下面的例子是没有现实生活中的代码,它只是为了明确的问题是什么:

//Example ONE: is this faster 
std::vector<int> foo; 
for(int i = 0; i < 100; ++i) 
{ 
    foo.clear(); 
    for(int j = 0; j < 100; ++j) 
    { 
     foo.push_back(i+j); 
    } 
} 

//Example TWO: or is that faster? 
for(int i = 0; i < 100; ++i) 
{ 
    std::vector<int> foo; 
    for(int j = 0; j < 100; ++j) 
    { 
     foo.push_back(i+j); 
    } 
} 
+0

这些东西不是依赖于实现吗? –

+6

配置文件。 Boooooring! –

+3

为什么所有的downvotes? – Daniel

回答

7

clear()无法按合同解除分配vector内存,而不是仅仅将内部“大小”标志到0,这样的方法会更快。

+1

不止是“稍微”,我会说。 –

+1

我不知道释放内存的任何实现。 –

+0

@大卫:创建一个新的矢量呢! :D [编辑:是的,好吧,让老的死] –

0

示例2对std :: vector中的数组重复了堆分配。示例1的速度更快,因为它避免了在堆上重复分配内存,除非需要在内部调整内存大小。

+0

's /在堆上分配内存/动态分配内存/' –

0

您必须为您的编译器运行基准测试。 clear()和'分配'方法是依赖于实现的。

+0

矢量永远不会缩小的容量根本不依赖于实现。 [编辑:虽然C++ 11 _does_有'shrink_to_fit'] –

+0

@Tomalak:我其实在想这件事。标准中没有具体的条款禁止实现实际释放内存。一个*缩小的向量在很多情况下很难实现(同时保持'push_back'的*分期不变的时间*成本),但我认为它不可能*,并且对于一般情况'清除',具体清除()'我没有看到任何理由为什么一致性实现无法释放内存(然后,我没有看过这个标准寻找这种特殊情况......) –

+0

@大卫:我也一直在探讨。我看不到任何保证'clear' *必须*调用'reserve'。这似乎相当强烈地暗示给我,但没有说明。 –

2

这取决于std::vector在C++中,您使用标准库的实现,但它很可能是第一种情况下会更快,因为当你调用std::vector::clear大多数的实现实际上并不自由分配的内存。因此,第一次在第一次执行内部循环时不执行重复分配。

0

既清除载体和降低其能力,以您的实现的最低,Scott Meyers建议交换技巧

std::vector<int>().swap(foo); 

这也将不是通过手卷环路到矢量迭代速度更快恢复其内容。

1

是的。不,第一个可能更快。这取决于。唯一有用的答案来自您在自己的环境中分析自己的代码。

尝试分析你的代码,看看会发生什么。编译your program at ideone显示,对于一个特定的编译器/操作系统/机器/运行,你的第一个例子加快4倍。

this program显示了一个中间解决方案,该编译器/ os/machine/run的中间解决方案比#2更快,比#1更慢。

0

在这种特定情况下,大多数机器上的重用情况可能会更快。您正在存储不需要销毁的原始数据(甚至有一个析构函数)。另一方面,如果矢量包含非POD对象,每个元素将被clear的调用破坏。第三方面,所有的累积数据最终都需要被破坏。