Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is std::find implemented this way?

Tags:

c++

std

stl

I happen to run into the source of std::find and find it confusing to me. Basically it divides the count of items by 4 and do the compare 4 in each round:

template<typename _RandomAccessIterator, typename _Tp>
_RandomAccessIterator
__find(_RandomAccessIterator __first, _RandomAccessIterator __last,
   const _Tp& __val, random_access_iterator_tag)
{
  typename iterator_traits<_RandomAccessIterator>::difference_type
__trip_count = (__last - __first) >> 2;

  for (; __trip_count > 0; --__trip_count)
{
  if (*__first == __val)
    return __first;
  ++__first;

  if (*__first == __val)
    return __first;
  ++__first;

  if (*__first == __val)
    return __first;
  ++__first;

  if (*__first == __val)
    return __first;
  ++__first;
}

  switch (__last - __first)
{
case 3:
  if (*__first == __val)
    return __first;
  ++__first;
case 2:
  if (*__first == __val)
    return __first;
  ++__first;
case 1:
  if (*__first == __val)
    return __first;
  ++__first;
case 0:
default:
  return __last;
}
}

I have no idea why it's done this way. Looks like some optimization. But I don't think this will take advantage of multi-core that easy. This is in a single thread anyway.

Any ideas?

like image 704
eltonsky Avatar asked Feb 18 '13 12:02

eltonsky


People also ask

What algorithm does std :: find use?

The algorithm to use is std::binary_search , that directly returns a bool representing whether the searched value has equivalent elements in the collection.

How are STD vectors implemented?

It's implemented by using an underlying array. It's not possible to implement a std::vector<T> with a linked list because the standard guarantees the elements in the list will be held in contiguous memory. Also, lookup time is important.

How fast is STD detected?

std::find on average runs in O(n/2) time whereas std::count is O(n) always.

Why STD find is not used for sorted collections?

But std::find is not really made for sorted collections because it uses equality and not equivalence, and it operates in linear time and not logarithmic time.

What is the basic std::pair class in C++?

Today we are going to talk about C++ basic std::pair class in a way how and why it is broken. std::pair first appeared in C++98 as a pretty basic class with a very simple semantics — you have two types T1 and T2, you can write std::pair<T1, T2> and access .first and .second members with all intuitive copy, assignment, comparison operators, etc.

What is the difference between std::pair and std::array?

This is a minor and debatable thing but std::pair with trivial and non default zero initialized scalars is zero initialized: In contrast, std::array does not initialize their elements with the default construction (if the underlying type is trivial) and leaves this for the user.


2 Answers

Looks like loop unwinding, also known as loop unrolling.

like image 99
Some programmer dude Avatar answered Oct 01 '22 09:10

Some programmer dude


It's loop unrolling. The result is the same, but it's friendlier for the processor.

The asymptotic complexity is the same though.

like image 28
Luchian Grigore Avatar answered Oct 01 '22 09:10

Luchian Grigore