the test code is like this ,timer will output the elapsed time on destruction
uint64_t res1 = 0, res2 = 0;
void test_accumulate_bind_function(uint64_t& x, uint64_t i)
{
x += i;
}
uint64_t res1 = 0, res2 = 0, res3 = 0, res4=0;
template <typename Function>
void do_loop_ref(Function & func, const uint64_t upper_limit = 100000)
{
for (uint64_t i = 0; i < upper_limit; ++i)
func(i);
}
template <typename Function>
void do_loop_forward(Function && func, const uint64_t upper_limit = 100000)
{
Function f(std::forward<Function>(func));
for (uint64_t i = 0; i < upper_limit; ++i)
f(i);
}
template <typename Function>
void do_loop_copy(Function func, const uint64_t upper_limit = 100000)
{
for (uint64_t i = 0; i < upper_limit; ++i)
func(i);
}
void test_bind_copy()
{
{
namespace arg = std::placeholders;
uint64_t x = 0;
auto accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);
std::cout << "reference:";
timer t;
do_loop_ref(accumulator);
res1 = x;
}
{
namespace arg = std::placeholders;
uint64_t x = 0;
auto accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);
std::cout << "copy:";
timer t;
do_loop_copy(accumulator);
res2 = x;
}
{
namespace arg = std::placeholders;
uint64_t x = 0;
auto accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);
std::cout << "localcopy:";
timer t;
do_loop_forward(accumulator);
res3 = x;
}
{
namespace arg = std::placeholders;
uint64_t x = 0;
auto accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);
std::cout << "move:";
timer t;
do_loop_forward(std::move(accumulator));
res4 = x;
}
printf("res1:%lld, res2:%lld, res3:%lld, res4:%lld\n", res1, res2, res3, res4);
}
void test_copy()
{
{
uint64_t x = 0;
auto accumulator = [&x](uint64_t i){ return x += i; };
std::cout << "reference:";
timer t;
do_loop_ref(accumulator);
res1 = x;
}
{
uint64_t x = 0;
auto accumulator = [&x](uint64_t i){ return x += i; };
std::cout << "copy:";
timer t;
do_loop_copy(accumulator);
res2 = x;
}
{
uint64_t x = 0;
auto accumulator = [&x](uint64_t i){ return x += i; };
std::cout << "localcopy:";
timer t;
do_loop_forward(accumulator);
res3 = x;
}
{
uint64_t x = 0;
auto accumulator = [&x](uint64_t i){ return x += i; };
std::cout << "move:";
timer t;
do_loop_forward(std::move(accumulator));
res4 = x;
}
printf("res1:%lld, res2:%lld, res3:%lld, res4:%lld\n", res1, res2, res3, res4);
}
int main()
{
test_copy();
test_bind_copy();
}
on my computer(vs2013) the output is:
reference: 196 copy: 65 localcopy: 196 move: 64
res1:4999950000, res2:4999950000, res3:4999950000, res4:4999950000
reference: 359 copy: 361 localcopy: 358 move: 358
res1:4999950000, res2:4999950000, res3:4999950000, res4:4999950000
so why in lambda call, pass by value is so faster than by reference. also i test lambda capture a empty string by reference, the output is like above;but when capture a empty string by value, ref and copy cost time will be approach.
bashrc's answer remind me, and i add two test, the result is interesting,move cost almost the same as pass by value, but if copy cost most time, why pass by value is faster than by reference;