Angus Leeming wrote:
> 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
and again, where case 3 actually does what is expected of it ;-)
Here I get run-time ratios (for 10000000 loops) of
boost::bind / Named Functor == 1.89
boost::function / Named Functor == 1.89
boost::lambda / Named Functor == 2.45
Draw your own conclusions.
--
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 == 3
function<bool(Foo const &)> const same_name =
bind(std::equal_to<std::string>(),
bind(&Foo::name, _1),
search_name);
#endif
for (int i = 0; i != 10000000; ++i) {
FooVec::const_iterator const it =
std::find_if(begin, end,
#if CASE == 1
SameNames(search_name));
#elif CASE == 2
bind(std::equal_to<std::string>(),
bind(&Foo::name, _1),
search_name));
#elif CASE == 3
same_name);
#elif CASE == 4
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;
}