Lars Gullik Bjønnes wrote:
> Angus Leeming <[EMAIL PROTECTED]> writes:
>
> | $ size trial_case?
> | text data bss dec hex filename
> | 7850 816 8 8674 21e2 trial_case1
> | 9510 840 16 10366 287e trial_case2
> | 9530 872 8 10410 28aa trial_case3
>
> With gcc 3.4:
>
> size trial_case? trial_case?.o
> text data bss dec hex filename
> 5435 356 164 5955 1743 trial_case1
> 6907 356 172 7435 1d0b trial_case2
> 7120 356 168 7644 1ddc trial_case3
> 2926 8 1 2935 b77 trial_case1.o
> 4367 8 10 4385 1121 trial_case2.o
> 4583 8 6 4597 11f5 trial_case3.o
>
> I did some performance test as well, running the find_if 10000000
> times for each of the cases.
>
> runtime ratio loops/sec
> case 1: 5.070s 1.0 1972386
> case 2: 7.965s 1.57 1255492
> case 3: 11.341s 2.236 881756
>
> I am not afraid of using any of these techniques in real code.
For completeness, here is the same code with an additional
boost::function test:
$ size bind_lambda?
dec hex filename
8799 225f bind_lambda1 // Named Functor
10508 290c bind_lambda2 // boost::bind
15894 3e16 bind_lambda3 // boost::function
10536 2928 bind_lambda4 // boost::lambda
--
Angus
#if !defined(CASE) || (CASE != 1 && CASE != 2 && CASE != 3 && CASE != 4)
#error Please compile -DCASE=[1234]
#endif
#if CASE == 2
#include <boost/bind.hpp>
using boost::bind;
#endif
#if CASE == 3
#include <boost/bind.hpp>
#include <boost/function.hpp>
using boost::bind;
using boost::function;
#endif
#if CASE == 4
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
using boost::lambda::_1;
using boost::lambda::bind;
#endif
#include <iostream>
#include <string>
#include <vector>
class Foo {
std::string name_;
public:
Foo(std::string const & name) : name_(name) {}
std::string const & name() const { return name_; }
};
#if CASE == 1
class SameNames {
std::string name_;
public:
SameNames(std::string const & name) : name_(name) {}
bool operator()(Foo const & foo) const
{ return name_ == foo.name(); }
};
#endif
int main()
{
char const * const names[] = {
"alfred", "ben", "chris", "david", "edgar",
"fred", "graham", "henry", "ian", "james",
"kenneth", "laurie", "mark", "nigel", "oprah",
"peter", "quentin", "rashid", "stewart",
"thomas", "uriah", "veronique", "william",
"xang", "yashin", "zebedee"
};
std::size_t const names_size = sizeof(names) / sizeof(names[0]);
typedef std::vector<Foo> FooVec;
FooVec const foovec(names, names + names_size);
std::string const search_name = "william";
FooVec::const_iterator const begin = foovec.begin();
FooVec::const_iterator const end = foovec.end();
#if CASE == 1
FooVec::const_iterator const it =
std::find_if(begin, end,
SameNames(search_name));
#elif CASE == 2
FooVec::const_iterator const it =
std::find_if(begin, end,
bind(std::equal_to<std::string>(),
bind(&Foo::name, _1),
search_name));
#elif CASE == 3
function<bool(Foo const &)> same_name =
bind(std::equal_to<std::string>(),
bind(&Foo::name, _1),
search_name);
FooVec::const_iterator const it = begin;
std::find_if(begin, end, same_name);
#elif CASE == 4
FooVec::const_iterator const it =
std::find_if(begin, end,
bind(&Foo::name, _1) == search_name);
#endif
std::cout << "Name '" << search_name << "' ";
if (it == end)
std::cout << "not found";
else
std::cout << "found at pos " << std::distance(begin, it);
std::cout << std::endl;
return 0;
}