zoukankan      html  css  js  c++  java
  • 对vector与deque插值与遍历的性能数据

     1 std::vector<int> vecint;
     2 std::deque<int> queint;
     3 clock_t t0, t1;
     4 
     5 int size = 1000000;
     6 
     7 t0 = clock();
     8 for (int i = 0; i < size; ++i)
     9 {
    10     vecint.push_back(i);
    11 }
    12 t1 = clock();
    13 //vector的push_back速度,共350ms,毕竟有realloc和copy的过程
    14 std::wcout<<t1 - t0<<std::endl;
    15 
    16 t0 = clock();
    17 for (int i = 0; i < size; ++i)
    18 {
    19     queint.push_back(i);
    20 }
    21 t1 = clock();
    22 //而deque因为没有realloc和copy的过程,只用了340ms,其实也没快多少
    23 //不过要是push_front,就会快非常多了
    24 std::wcout<<t1 - t0<<std::endl;
    25 
    26 int i;
    27 
    28 t0 = clock();
    29 for (auto it = vecint.begin(); it != vecint.end(); ++it)
    30 {
    31     i = *it;
    32 }
    33 t1 = clock();
    34 //用iterator遍历vector,花费882ms,不推荐这么遍历
    35 std::wcout<<t1 - t0<<std::endl;
    36 
    37 t0 = clock();
    38 for (auto it = queint.begin(); it != queint.end(); ++it)
    39 {
    40     i = *it;
    41 }
    42 t1 = clock();
    43 //用iterator遍历deque,花费768ms,对于deque这已经是最快的方法了
    44 std::wcout<<t1 - t0<<std::endl;
    45 
    46 t0 = clock();
    47 for (int i = 0; i < size; ++i)
    48 {
    49     i = vecint[i];
    50 }
    51 t1 = clock();
    52 //用下标遍历vector,花费55ms,推荐的方式
    53 std::wcout<<t1 - t0<<std::endl;
    54 
    55 t0 = clock();
    56 for (int i = 0; i < size; ++i)
    57 {
    58     i = queint[i];
    59 }
    60 t1 = clock();
    61 //用下标遍历deque,花费1548ms,比iterator方式慢了一倍
    62 std::wcout<<t1 - t0<<std::endl;
    63 
    64 t0 = clock();
    65 for (unsigned int i = 0; i < vecint.size(); ++i)
    66 {
    67     i = vecint[i];
    68 }
    69 t1 = clock();
    70 //一个小细节,即便使用下标遍历,最好把size提前取出来,
    71 //每次访问一下还是要牺牲性能的,花费了82ms。
    72 std::wcout<<t1 - t0<<std::endl;

    而list的push_back性能和遍历性能跟它们就更没有可比性了。

    以上数据引自 http://gfdice.iteye.com/blog/1313520 ,为在VS2010中,使用Dinkumware STL测试的数据。

    我的自测数据(1000000条):

    #include <vector>
    #include <deque>
    #include <sys/time.h>
    #include <iostream>
    
    using std::vector;
    using std::deque;
    using std::cout;
    using std::endl;
    
    //struct timeval {
    //    long    tv_sec;         /* seconds */
    //    long    tv_usec;        /* and microseconds 微秒 */
    //};
    
    void tv_sub(struct timeval *out, struct timeval *in)
    {
        if ((out->tv_usec -= in->tv_usec) < 0) {
            --out->tv_sec;
            out->tv_usec += 1000000;
        }
        out->tv_sec -= in->tv_sec;
    }
    
    int main()
    {
        static timeval tv_start, tv_stop;
        int MAXSIZE = 1000000;
        vector<int*> vec(MAXSIZE, new int(0));

    int tt = 0; gettimeofday(&tv_start, NULL); for(vector<int*>::iterator it = vec.begin(); it != vec.end(); ++it) tt = **it; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "iteratror: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; gettimeofday(&tv_start, NULL); for (int i = 0; i < MAXSIZE; ++i) tt = *vec[i]; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "operator[]: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; deque<int*> deq(MAXSIZE, new int(0)); gettimeofday(&tv_start, NULL); for(deque<int*>::iterator it = deq.begin(); it != deq.end(); ++it) tt = **it; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "deq iteratror: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; gettimeofday(&tv_start, NULL); for (int i = 0; i < MAXSIZE; ++i) tt = *deq[i]; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "deq operator[]: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; }

    vector iterator:  31,718 μs

    vector [ ]:            9,515 μs

    deque iterator:  37,956 μs

    deque [ ]:        132,348 μs

    对vector遍历最佳是用operator[],deque则是用iterator更好。

    另,关于多线程网上有人这样说,觉得在概念上更清晰了:

    标准C++里没有线程这个概念,也不支持多线程

    锁会导致性能低下,实际工作中线程很少需要读写同一套数据,线程是用来解决io等待的;多线程能不能提高程序的性能很难说,如果问题本身就具有原子性,不能分割,多线程就没有意义。

    尽量减少线程的使用,尽量减小锁的粒度。

  • 相关阅读:
    failed to push some refs to 'git@github.com:cq1415583094/MyBatis.git'解决办法
    MyBatis 安装和配置
    MyBatis入门
    LinkedList 源码分析
    ArrayList 源码分析
    什么是注解?
    什么是泛型?
    什么是反射?
    php针对各数据库系统对应的扩展
    DedeCMS文章标题长度最全修改方法
  • 原文地址:https://www.cnblogs.com/edgarli/p/2785111.html
Copyright © 2011-2022 走看看