iterator vs reverse_iterator

Mig*_*gel 5 c++ performance stl stdmap

std::map用来存储很多元素(元素对),我有一点"怀疑".更重要的是有效地遍历我所有的元素std::map,iteratorreverse_iterator

vla*_*adr 27

为了记录在案,提领reverse_iteratorstd::mapstd::set容器是慢一倍的使用iterator-既-O3 GCC 3.4.6和MSVC在Intel/AMD处理器(几乎3倍于PPC架构一样慢.)同样适用于const_reverse_iteratorconst_iterator.这是因为reverse_iterator 实际上指向紧随树节点之后的树节点被解除引用的事实,因此额外的工作. std::vector迭代器表现出更温和的差异(reverse_iterator在PPC上只有约30%的速度,在Intel/AMD上几乎无法区分.)顺便说一下,std::vector迭代器比一个std::mapstd::set迭代器快约20倍.

#include <set>
#include <vector>
#include <stdio.h>
#ifdef _WIN32
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <time.h>

#define CONTAINER std::set< int >

double
mygettime(void) {
# ifdef _WIN32
  struct _timeb tb;
  _ftime(&tb);
  return (double)tb.time + (0.001 * (double)tb.millitm);
# else
  struct timeval tv;
  if(gettimeofday(&tv, 0) < 0) {
    perror("oops");
  }
  return (double)tv.tv_sec + (0.000001 * (double)tv.tv_usec);
# endif
}


int main() {
  int i, x = 0;
  CONTAINER bla;
  for (i = 0; i < 10000; bla.insert(bla.end(), i++)) ;

  double t1 = mygettime();

  for (i = 0; i < 100; ++i) {
    for (CONTAINER::iterator it = bla.begin(); it != bla.end(); ++it) {
      x ^= *it;
    }
  }

  printf("forward: %f\n", mygettime() - t1);

  double t2 = mygettime();

  for (i = 0; i < 100; ++i) {
    for (CONTAINER::reverse_iterator it = bla.rbegin(); it != bla.rend(); ++it) {
      x ^= *it;
    }
  }

  printf("reverse: %f\n", mygettime() - t2);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 投票赞成回答提出的问题.一些微观优化是如此明显,以至于不实现它们应被视为糟糕的编程实践/错误...但我在一个性能关键领域工作; 如果由我决定,C++将被重命名为"++ C". (8认同)

Nav*_*een 13

真的有关系吗?这些是您必须尝试避免恕我直言的微优化的类型.此外,即使迭代时间因地图中的大量元素而发生变化,您尝试迭代这样一个大地图的所有元素这一事实意味着您很可能选择了错误的数据结构.