C++ Pirate: Lambda vs Bind (五)

2014-11-23 22:54:04 · 作者: · 浏览: 22
class timer
{
public:
typedef std::chrono::high_resolution_clock clock;
typedef clock::time_point time_point;
typedef clock::duration duration;
public:
timer()
{
reset();
}
void reset()
{
_starttime = clock::now();
}
duration elapsed() const
{
return clock::now() - _starttime;
}
protected:
time_point _starttime;
};
bool test_timer()
{
using std::chrono::milliseconds;
typedef timer::duration duration;
const milliseconds sleep_time(500);
timer t;
std::this_thread::sleep_for(sleep_time);
duration recorded = t.elapsed();
// make sure the clock and this_thread::sleep_for is precise within one millisecond (or at least in agreement as to
// how inaccurate they are)
return (recorded - milliseconds(1) < sleep_time)
&& (recorded + milliseconds(1) > sleep_time);
}
template
void volatile_write(const T& x)
{
volatile T* p = new T;
*p = x;
delete p;
}
template
void run_test(const std::string& name, Function func)
{
std::cout << name;
timer t;
volatile_write(func());
timer::duration duration = t.elapsed();
std::cout << '\t' << duration.count() << std::endl;
}
template
void do_test_loop(Function func, const uint64_t upper_limit = 1000000000ULL)
{
for (uint64_t i = 0; i < upper_limit; ++i)
func(i);
}
uint64_t test_accumulate_lambda()
{
uint64_t x = 0;
auto accumulator = [&x] (uint64_t i) { x += i; };
do_test_loop(accumulator);
return x;
}
void test_accumulate_bind_function(uint64_t& x, uint64_t i)
{
x += i;
}
uint64_t test_accumulate_bind()
{
namespace arg = std::placeholders;
uint64_t x = 0;
std::function accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);
do_test_loop(accumulator);
return x;
}
uint64_t test_accumulate_bound_lambda()
{
uint64_t x = 0;
std::function accumulator = [&x] (uint64_t i) { x += i; };
do_test_loop(accumulator);
return x;
}
#if USE_BOOST
uint64_t test_accumulate_boost_bind()
{
uint64_t x = 0;
boost::function accumulator = boost::bind(&test_accumulate_bind_function, boost::ref(x), _1);
do_test_loop(accumulator);
return x;
}
uint64_t test_accumulate_boost_bound_lambda()
{
uint64_t x = 0;
boost::function accumulator = [&x] (uint64_t i) { x += i; };
do_test_loop(accumulator);
return x;
}
#endif
int main()
{
if (!test_timer())
{
std::cout << "Failed timer test." << std::endl;
return -1;
}
run_test("Accumulate (lambda) ", &test_accumulate_lambda);
run_test("Accumulate (bind) ", &test_accumulate_bind);
run_test("Accumulate (bound lambda) ", &test_accumulate_bound_lambda);
#if USE_BOOST
run_test("Accumulate (boost bind) ", &test_accumulate_boost_bind);
run_test("Accumulate (boost bound lambda)", &test_accumulate_bound_lambda);
#endif
}