我曾认为std::vector只是动态数组的一个简单封装,因此它们的性能应该相当。互联网和stackoverflow本身也给出了同样的答案。然而,当我自己测试时,发现有很大的差异。以下是代码。我尝试了VC++ 2012(发布版本)和带有优化标志-O2的MinGW。
new、malloc和calloc的时间约为0.005秒,而std::vector在两个编译器上都需要0.9秒。std::vector本质上很慢吗?还是我的代码有严重缺陷?
new、malloc和calloc的时间约为0.005秒,而std::vector在两个编译器上都需要0.9秒。std::vector本质上很慢吗?还是我的代码有严重缺陷?
#define _SCL_SECURE 0
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <time.h>
struct timer
{
clock_t start;
timer()
{
start=clock();
}
~timer()
{
double t=static_cast<double>(clock()-start)/CLOCKS_PER_SEC;
printf("%lf\n", t);
}
};
int main()
{
const size_t len=(1<<28);
{
timer t;
int *d=new int[len];
printf("%d\n",d[len-1]);//prevent compiler from optimizing away
//useless allocation and deallocation
delete[] d;
}
{
timer t;
int *d=(int *)malloc(len*sizeof(int));
printf("%d\n", d[len-1]);
free(d);
}
{
timer t;
std::vector<int> d(len);
printf("%d\n", d[len-1]);
}
{
timer t;
int *d=(int *)calloc(len, sizeof(int));
printf("%d\n", d[len-1]);
free(d);
}
return 0;
}
编辑 1
按建议,我尝试了创建动态数组的其他方式。
new
:为0.005malloc
:为0.005calloc
:为0.005malloc
+memset
:为1.244vector(len)
:为1.231vector(len, 0)
:为1.234vector.reserve(len)
:为0.005
因此,罪魁祸首确实是零初始化而不是分配或释放内存。这意味着,如果需要一个零初始化的数组,即使vector
具有默认初始化所有元素的构造函数,也不能使用它。
此外,这不仅仅是我的想法。我的一门课程的最终项目是根据所花费的时间评分的,我使用了几个 vector
来分配一个巨大的内存缓冲区,而不是使用new
来保证异常安全性,并且我们的教科书鼓励使用STL。直到今天我才意识到由于这个原因我失去了一些分数。很遗憾。
编辑 2
今天我在Ubuntu 13.04 x64上尝试了Clang 3.2,而std :: vector现在不再需要花费那么长时间进行初始化。事实上,vector现在是最快的!也许这真的是编译器优化问题,而不是std :: vector设计本身的问题。
vector
和其他代码的重要区别在于,vector
在初始化内存时会将其清零,而其他代码则不会(除了calloc
)。如果您将new
替换为new int[len]()
,它会与vector
执行相同的时间。我认为calloc
在某种程度上进行了优化(例如,它可能会请求清零的内存,而不是显式地清零内存本身)。 - Mankarse#define _SCL_SECURE 0
是什么意思? - James McNellis