iterator vs reverse_iterator

2019-02-18 03:52发布

I'm using std::map to store a lot of elements (pairs of elements) and I have a "little" doubt. What is more efficient to iterate all elements over my std::map, iterator or reverse_iterator?

6条回答
家丑人穷心不美
2楼-- · 2019-02-18 04:12

Does it really matter? these are the types of the micro optimizations you must try to avoid IMHO. Also, even if the iteration time changes for very large number of elements in the map, the fact that you are trying to iterate through all the elements of such a big map means that most probably you have chosen a wrong data structure.

查看更多
Anthone
3楼-- · 2019-02-18 04:12

Unless you have profiled your code and found there to be a significant difference, I just wouldn't be concerned about it.

"Premature optimization is the root of all evil." - Donald Knuth

查看更多
相关推荐>>
4楼-- · 2019-02-18 04:20

There will likely be no difference. std::reverse_iterator is just a template shim that translates ++'s to --'s at compile time.

For a vector or other contiguous storage container, a forward iterator might interact very slightly better with the cache than a reverse iterator would (unlikely you'd be able to detect it), but for a tree-based container it won't make any difference at all--there won't be any locality of reference to exploit.

查看更多
\"骚年 ilove
5楼-- · 2019-02-18 04:24

Me think it does not make sense to use a reverse_iterator; it's counter intuitive.

It would make the code harder to understand, someone will look at the code and go "wtf"; and if you need to put a comment to explain why, it probably means it's not good code to start with.

查看更多
Emotional °昔
6楼-- · 2019-02-18 04:36

I am wondering the need for iteration. Map holds the key-value pairs and normally you use it for the lookup. If you still need to iterate the map for some reasons ( may be deleting pointers contained inside the map etc) then you can use std::for_each. Forget the micro optimizations and you can try to increase the code readability.

查看更多
Luminary・发光体
7楼-- · 2019-02-18 04:37

For the record, dereferencing reverse_iterator on std::map and std::set containers is twice as slow as using iterator -- with both -O3 gcc 3.4.6 and MSVC on Intel/AMD processors (almost 3x as slow on PPC architectures.) Same holds for const_reverse_iterator vs. const_iterator. This is due to the fact that reverse_iterator actually points to the tree node immediately following the tree node to be dereferenced, hence the extra work. std::vector iterators exhibit a much milder difference (reverse_iterator is only ~30% slower on PPC, virtually indistinguishable on Intel/AMD.) Incidentally, a std::vector iterator is about 20x faster than a std::map or std::set iterator.

#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;
}
查看更多
登录 后发表回答