为什么emplace_hint比插入地图慢?

时间:2018-08-14 15:12:56

标签: c++ performance c++11 stdmap

uint64_t get_ticks(){
    struct timeval now;
    gettimeofday(&now, NULL);
    uint64_t r = ((now.tv_sec) * 1000) +((now.tv_usec) / 1000);
    return r;}

emplace_hint用法如下:

    #define MAX_INSRT 500000
int main(int argc,char** argv)
{
     int last;
     map<int,int> mps;
     map<int,int>::iterator it;
     uint64_t beg,end;
     string str;
     it = mps.end();
     beg=get_ticks();
     for(int i=0;i<MAX_INSRT;i++) {
         int x = rand()%200000000;
         it = mps.lower_bound(x);
         if (it != mps.end() && it->first == x) {
             ;
         } else {
             mps.emplace_hint(it,x,i);
         }
     }
     end=get_ticks();
     printf("cost time = %lu, map size = %zu\n",end-beg,mps.size());
     return 0;
}

输出: 花费时间= 740,地图大小= 499343

插入这样的用法:

#define MAX_INSRT 500000
int main(int argc,char** argv)
{
     int last;
     map<int,int> mps;
     map<int,int>::iterator it;
     uint64_t beg,end;
     string str;
     it = mps.end();
     beg=get_ticks();
     for(int i=0;i<MAX_INSRT;i++) {
         int x = rand()%200000000;
         mps.insert(map<int,int>::value_type(x,i));
     }
     end=get_ticks();
     printf("cost time = %lu, map size = %zu\n",end-beg,mps.size());
     return 0;
}

输出: 花费时间= 691,地图尺寸= 499343

编译: $ g ++ -g -std = c ++ 11 -o new_map new_map.cc

g ++版本: gcc版本4.9.2(GCC)

不明白为什么会发生...

1 个答案:

答案 0 :(得分:3)

我在wandbox.org上重复了测试(在示例代码中添加了一些化妆品之后):

#include <sys/time.h>
#include <iomanip>
#include <iostream>
#include <map>

const int N = 10;
const int Max = 100000;

uint64_t get_ticks()
{
  struct timeval now;
  gettimeofday(&now, NULL);
  const uint64_t r = ((now.tv_sec) * 1000) +((now.tv_usec) / 1000);
  return r;
}

uint64_t checkInsert()
{
  std::map<int, int> map;
  const uint64_t t0 = get_ticks();
  for (int i = 0; i < Max; ++i) {
    const int x = rand() % 200000000;
    map.insert(std::make_pair(x, i));
  }
  const uint64_t t1 = get_ticks();
  return t1 - t0;
}

uint64_t checkEmplace()
{
  std::map<int, int> map;
  const uint64_t t0 = get_ticks();
  for (int i = 0; i < Max; ++i) {
    const int x = rand() % 200000000;
    const std::map<int, int>::iterator iter = map.lower_bound(x);
    if (iter == map.end() || iter->first != x) {
      map.emplace_hint(iter, x, i);
    }
  }
  const uint64_t t1 = get_ticks();
  return t1 - t0;
}

int main()
{
  for (int i = 1; i <= N; ++i) {
    uint64_t tIns = checkInsert();
    uint64_t tEmp = checkEmplace();
    std::cout << std::setw(10) << tIns << std::setw(10) << tEmp << '\n';
  }
  // done
  return 0;
}

编译器是gcc HEAD 9.0.0 201808-O2

输出:

    71        62
    45        76
    90        75
    81        77
    83        81
    79        70
    87       102
    92        85
    85        67
    78        96

Live Demo on wandbox

我的解释:

不可能测量std::map::insert()std::map::emplace_hint()之间的显着差异-至少对于std::map<int, int>而言不是。

如果完全存在,测量噪声似乎掩盖了实验中的任何真实差异。