为了量化类C数组和C++向量的性能差异,我写了这个小程序。 https://github.com/rajatkhanduja/Benchmarks/blob/master/C%2B%2B/vectorVsArray.cpp
为了在共同的基础上比较它们,我决定测试随机和顺序访问。我添加了迭代器,只是为了比较它们(但这不是问题的重点)。
对于具有 7.7 GB RAM 且阵列/矢量大小为 100 万的 64 位 Linux 计算机,结果如下:
- 写入数组所需的时间:12.0378 ms 按
- 顺序从数组读取所花费的时间。 : 2.48413 ms
- 从数组中随机读取所需的时间。 : 37.3931 ms
- 写入动态数组所花费的时间。 : 11.7458 ms 按
- 顺序从动态数组读取所花费的时间。 : 2.85107 ms
- 从动态数组随机读取所需的时间。 : 36.0579 ms
- 使用索引写入向量所需的时间。 : 11.3909 ms
- 使用索引按顺序从向量读取所花费的时间。 : 4.09106 ms
- 使用索引随机读取向量所花费的时间:39 ms
- 使用迭代器写入向量所花费的时间。 : 24.9949 ms
- 使用迭代器从向量读取所需的时间。 : 18.8049 ms
的大小是在初始化时设置的,不会更改,因此不会调整向量的大小(程序中的断言有助于验证这一点)。时间不包括任何静态分配的数组、动态分配的数组或向量的初始化时间。
据统计,写入 Vector 的时间比数组短,但从 vector 读取的时间是数组的两倍。
差异很小,但是有没有解释为什么会有性能差异?测试有问题吗?我希望两者以相同的速度执行。重复该测试显示出相同的趋势。
代码:
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sys/time.h>
#include <cassert>
#define ARR_SIZE 1000000
using std::string;
void printtime (struct timeval& start, struct timeval& end, string str);
int main (void)
{
int arr[ARR_SIZE];
int tmp;
struct timeval start, stop;
srand (time (NULL));
/* Writing data to array */
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
arr[i] = rand();
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to write to array."));
/* Reading data from array */
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = arr[i];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from array sequentially."));
/* Reading data from array randomly*/
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = arr[rand() % ARR_SIZE];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from array randomly."));
int *darr = (int *) calloc (sizeof (int), ARR_SIZE);
/* Writing data to array */
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
darr[i] = rand();
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to write to dynamic array."));
/* Reading data from array */
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = darr[i];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from dynamic array sequentially."));
/* Reading data from dynamic array randomly*/
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = darr[rand() % ARR_SIZE];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from dynamic array randomly."));
std::vector<int> v(ARR_SIZE);
assert (v.capacity() == ARR_SIZE);
/* Writing to vector using indices*/
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
v[i] = rand();
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to write to vector using indices."));
assert (v.capacity() == ARR_SIZE);
/* Reading from vector using indices*/
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = v[i];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from vector using indices, sequentially."));
/* Reading data from dynamic array randomly*/
gettimeofday (&start, NULL);
for (int i = 0; i < ARR_SIZE; i++)
{
tmp = v[rand() % ARR_SIZE];
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from vector using indices, randomly."));
std::vector<int> v2(ARR_SIZE);
/* Writing to vector using iterators*/
gettimeofday (&start, NULL);
std::vector<int>::iterator itr, itr_end;
for (itr = v2.begin(), itr_end = v2.end(); itr != itr_end; itr++)
{
*itr = rand();
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to write to vector using iterators."));
/* Reading from vector using iterators*/
gettimeofday (&start, NULL);
for (itr = v2.begin(), itr_end = v2.end(); itr != itr_end; itr++)
{
tmp = *itr;
}
gettimeofday (&stop, NULL);
printtime (start, stop, string ("Time taken to read from vector using iterators."));
return 0;
}
void printtime (struct timeval& start, struct timeval& end, string str)
{
double start_time, end_time, diff;
start_time = ((start.tv_sec) * 1000 + start.tv_usec/1000.0);
end_time = ((end.tv_sec) * 1000 + end.tv_usec/1000.0);
diff = end_time - start_time;
std::cout << str << " : " << diff << " ms" << std::endl;
}
编辑
正如评论中所建议的,这里有更多信息:-
- 编译器 :- g++ - 4.5.2
- 标志 :- 无(即默认值)
- 优化:- 无(我想在常规设置中测试行为。优化可能会改变程序的行为,例如,由于从不使用变量 tmp,读取向量/数组的步骤可能会完全跳过或减少到最后一个赋值。至少这是我所理解的)。
当然不是一个明确的答案,但你正在循环写入一个变量,这意味着编译器可以很容易地猜测顺序读取的最终结果应该是什么,从而优化循环。 由于它显然没有这样做,因此我认为没有绝对不支持迭代器方法的优化。 其他数字太接近,无法得出结论。