Skip to content

Instantly share code, notes, and snippets.

@mo-xiaoming
Created February 9, 2020 12:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mo-xiaoming/41cfa2b2210c9eb0bd9a0a99e07c92fa to your computer and use it in GitHub Desktop.
Save mo-xiaoming/41cfa2b2210c9eb0bd9a0a99e07c92fa to your computer and use it in GitHub Desktop.
Passing arguments by reference is waaaay better than fancy 'new' stuff
/*
auto const f = [inner](ParamType v) -> std::vector<int> {
for (int i = 0; i < inner; ++i)
v.push_back(i);
return ReturnType;
};
for (auto _ : state) {
for (auto n = 0; n < outer; ++n) {
v.clear();
v = f(v);
}
}
first value is outer loop counter, the second is inner loop counter
- bench_copy, pass by value, return by RVO
- bench_ref, pass/return by same parameter reference
- bench_rvalue, pass by rvalue reference, return by value
- bench_rvalue_move, pass by rvalue reference, return by move
1/1
bench_copy 28.93ns 100.00%
bench_ref 2.58ns 8.93%
bench_rvalue 26.19ns 90.51%
bench_rvalue_move 2.57ns 8.89%
1/500
bench_copy 1981.32ns 100.00%
bench_ref 370.15ns 18.68%
bench_rvalue 1563.07ns 78.89%
bench_rvalue_move 1052.58ns 53.12%
1/1000
bench_copy 3509.56ns 100.00%
bench_ref 727.01ns 20.72%
bench_rvalue 2967.37ns 84.55%
bench_rvalue_move 2096.75ns 59.74%
10/1
bench_copy 288.84ns 100.00%
bench_ref 29.34ns 10.16%
bench_rvalue 267.42ns 92.58%
bench_rvalue_move 31.85ns 11.03%
10/500
bench_copy 20090.87ns 100.00%
bench_ref 3703.97ns 18.44%
bench_rvalue 15208.50ns 75.70%
bench_rvalue_move 10674.25ns 53.13%
10/1000
bench_copy 35465.61ns 100.00%
bench_ref 7315.56ns 20.63%
bench_rvalue 29097.69ns 82.04%
bench_rvalue_move 21283.56ns 60.01%
*/
#include <algorithm>
#include <random>
#include <benchmark/benchmark.h>
static void generate_arg_pairs(benchmark::internal::Benchmark* b) {
for (int outer : {1, 10}) {
for (int inner : {1, 500, 1000}) {
b = b->ArgPair(outer, inner);
}
}
}
static void bench_copy(benchmark::State& state) {
std::vector<int> v;
auto const outer = state.range(0);
auto const inner = state.range(1);
auto const f = [inner](std::vector<int> v) -> std::vector<int> {
for (int i = 0; i < inner; ++i)
v.push_back(i);
return v;
};
for (auto _ : state) {
for (auto n = 0; n < outer; ++n) {
v.clear();
v = f(v);
}
}
}
BENCHMARK(bench_copy)->Apply(generate_arg_pairs);
static void bench_rvalue(benchmark::State& state) {
std::vector<int> v;
auto const outer = state.range(0);
auto const inner = state.range(1);
auto const f = [inner](std::vector<int>&& v) -> std::vector<int> {
for (int i = 0; i < inner; ++i)
v.push_back(i);
return v;
};
for (auto _ : state) {
for (auto n = 0; n < outer; ++n) {
v.clear();
v = f(std::move(v));
}
}
}
BENCHMARK(bench_rvalue)->Apply(generate_arg_pairs);
static void bench_rvalue_move(benchmark::State& state) {
std::vector<int> v;
auto const outer = state.range(0);
auto const inner = state.range(1);
auto const f = [inner](std::vector<int>&& v) -> std::vector<int> {
for (int i = 0; i < inner; ++i)
v.push_back(i);
return std::move(v);
};
for (auto _ : state) {
for (auto n = 0; n < outer; ++n) {
v.clear();
v = f(std::move(v));
}
}
}
BENCHMARK(bench_rvalue_move)->Apply(generate_arg_pairs);
static void bench_ref(benchmark::State& state) {
std::vector<int> v;
auto const outer = state.range(0);
auto const inner = state.range(1);
auto const f = [inner](std::vector<int>& v) {
for (int i = 0; i < inner; ++i)
v.push_back(i);
};
for (auto _ : state) {
for (auto n = 0; n < outer; ++n) {
v.clear();
f(v);
}
}
}
BENCHMARK(bench_ref)->Apply(generate_arg_pairs);
BENCHMARK_MAIN();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment