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;
}

Reply via email to