boostorg / algorithm

Boost.org algorithm module
http://boost.org/libs/algorithm
Boost Software License 1.0
114 stars 105 forks source link

any_of and any_of_equal call std::find_if and std::find respectively #3

Closed Kojirion closed 2 years ago

Kojirion commented 10 years ago

any_of calls std::find and checks against range end. STL implementations should be trusted to perform this more efficiently than the hand-written search.

All tests pass.

mclow commented 10 years ago

Except that they don't. Look at a standard library implementation of std::find (say, the one in libc++ at https://llvm.org/svn/llvm-project/libcxx/trunk/include/algorithm), and you'll see it's the exact same code.

What you've added is the overhead of copying two iterators (and a predicate, in the second case), and an additional procedure call (which may be inlined by the compiler).

I'm not strongly against this change, but I don't see the advantage of it, either.

Kojirion commented 10 years ago

In this simple benchmark:

https://gist.github.com/Kojirion/10776248

the current implementation performs worse than the rest. The C++11 implementation of std::any_of my gcc (4.8) calls none_of which in turn does call find_if. These calls can be expected to get - and do get - inlined.

Kojirion commented 10 years ago

Now that 1.56 is out, is there any chance this will be implemented? In this video (at 49:30):

http://vimeo.com/97349218#at=2910

Alexandrescu presents how to specialize find for random access iterators, claiming it is 3.8 times faster than a linear search.

I can also conceive an STL implementation where find does not return early, so as not to leak information. And so on. Hand-writing another linear search disregards such specializations and choices.

mclow commented 7 years ago

I tried your benchmark, and I got different results - the current implementation was equal to the fastest.

0.000021s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%) 0.000018s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%) 0.000020s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%) 0.000018s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%) 0.000019s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%)

(clang trunk, Mac OS X, libc++, -O3)