【发布时间】:2015-06-10 23:43:19
【问题描述】:
我正在尝试使用 Eratosthenes'Sieve 算法找到所有不大于 n 的素数,并且我有以下代码,筛子在向量和 C 数组中实现,我发现几乎在所有时间, C 数组总是更快。
使用向量:
int countPrimes_vector(int n) {
int res = 0;
vector<char>bitmap(n);
memset(&bitmap[0], '1', bitmap.size() * sizeof( bitmap[0]));
//vector<bool>bitmap(n, true); Using this one is even slower!!
for (int i = 2; i<n; ++i){
if(bitmap[i]=='1')++res;
if(sqrt(n)>i)
{
for(int j = i*i; j < n; j += i) bitmap[j] = '0';
}
}
return res;
}
使用 C 数组:
int countPrimes_array(int n) {
int res = 0;
bool * bitmap = new bool[n];
memset(bitmap, true, sizeof(bool) * n);
for (int i = 2; i<n; ++i){
if(bitmap[i])++res;
if(sqrt(n)>i)
{
for(int j = i*i; j < n; j += i) bitmap[j] = false;
}
}
delete []bitmap;
return res;
}
测试代码:
clock_t t;
t = clock();
int a;
for(int i=0; i<10; ++i)a = countPrimes_vector(8000000);
t = clock() - t;
cout<<"time for vector = "<<t<<endl;
t = clock();
int b;
for(int i=0; i<10; ++i)b = countPrimes_array(8000000);
t = clock() - t;
cout<<"time for array = "<<t<<endl;
输出:
time for vector = 32460000
time for array = 29840000
我测试了很多次,C数组总是更快。背后的原因是什么?
经常听说vector 和C 数组的性能是一样的,vector 应该一直作为标准容器使用。这种说法是真的,或者至少一般来说是这样吗?在什么情况下应该首选 C 数组?
编辑:
如下cmets提示,开启优化-O2或-O3后(原来是用g++ test.cpp编译的),vector与C数组的时间差不再有效,在某些场合@ 987654332@ 比 C 数组快。
【问题讨论】:
-
没有数据结构比不上数组,就这么简单?
-
您使用哪些编译器选项进行编译?优化设置对于这类问题非常重要。此外,我认为您所经历的轻微(实际上并不多)性能下降对于您获得的额外安全性和易用性而言非常小。
-
代码不等价。在一种情况下,您使用值 49 来表示逻辑真,使用 48 来表示假。在另一种情况下,您使用 1 并将其与 0 进行比较。到底为什么要这样做。
-
在未启用优化的情况下进行性能测试在很大程度上是没有意义的,因为您正在测试生成的可执行文件易于调试,而不是旨在以最高效率运行的可执行文件。
-
@Allanqunzi 另一个区别是,在某些实现中,
vector::operator[]将对未优化的构建执行范围检查,而您将在性能测试中为此付出巨大的代价。