加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – std :: vector如何比一个简单的数组更快?

发布时间:2020-12-16 05:48:41 所属栏目:百科 来源:网络整理
导读:我在一个循环缓冲区的基准测试中偶然发现.任何人都可以解释一个std :: vector如何在这个实例中胜过一个简单的数组? #include iostream#include vectorstruct uint_pair { unsigned int a,b; uint_pair (unsigned int x = 0,unsigned int y = 0) : a(x),b(y)
我在一个循环缓冲区的基准测试中偶然发现.任何人都可以解释一个std :: vector如何在这个实例中胜过一个简单的数组?
#include <iostream>
#include <vector>

struct uint_pair {
    unsigned int a,b;
    uint_pair (unsigned int x = 0,unsigned int y = 0) : a(x),b(y) {}
};

struct container {
    unsigned int pos;

#ifdef USE_VECTOR
    std::vector<uint_pair> data;
    container() : pos(0) { data.resize(16); }
#else
    uint_pair data[16];
    container() : pos(0) {}
#endif

    void add(uint_pair val) {
        data[++pos % 16] = val;
    }
};

int main() {
    container c;
    for (unsigned int i = 0; i < 1000000000; i++) c.add(uint_pair{i,i});
    std::cout << c.data[0].a << " " << c.data[0].b << std::endl;
}

这些是我使用GCC的结果(与Clang类似):

g++ -o bench -std=c++0x -Os main.cpp -D'USE_VECTOR'
real    0m8.757s
user    0m8.750s
sys     0m0.002s

g++ -o bench -std=c++0x -Os main.cpp
real    0m9.215s
user    0m9.209s
sys     0m0.002s

解决方法

以下是如何消除差异.而不是添加,请使用如下功能:
void set(unsigned int x,unsigned int y) {
    ++pos;
    data[pos % 16].a = x;
    data[pos % 16].b = y;
}

叫这样:

for (unsigned int i = 0; i < 1000000000; i++) c.set(i,i);

这与你完全一样,但它避免语义上创建一个临时对象.看起来当您使用向量时,编译器能够更好地优化临时性.

$g++-4.8 -o bench -std=c++11 -Os main.cpp -DUSE_VECTOR
$time ./bench 
999999999 999999999

real    0m0.635s
user    0m0.630s
sys 0m0.002s

$g++-4.8 -o bench -std=c++11 -Os main.cpp
$time ./bench 
999999999 999999999

real    0m0.644s
user    0m0.639s
sys 0m0.002s

在我的机器上,set和add方法产生与向量相同的性能.只有阵列显示出不同之处.为了进一步提供优化信息,如果使用-O0编译,那么数组方法稍快一些(但是比-Os都要慢10倍以上).

这并不能解释为什么编译器会对这两者有不同的看法.一个向量毕竟是由数组支持的.另外,std :: array的行为与C风格的数组相同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读