Skip to content

Instantly share code, notes, and snippets.

@Veedrac
Last active March 1, 2016 10:55
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 Veedrac/8331ebd66781d51cccd5 to your computer and use it in GitHub Desktop.
Save Veedrac/8331ebd66781d51cccd5 to your computer and use it in GitHub Desktop.
#include "benchmark/benchmark.h"
#include <algorithm>
class X {
private:
std::size_t size;
int *data;
public:
// You still keep the main three, the constructor,
// copy constructor and destructor,
X(std::size_t _size = 0):
size(_size), data(_size ? new int[_size]() : nullptr) {}
X(X const &other): X(other.size) {
std::copy(other.data, other.data + size, data);
}
virtual ~X() { delete[] data; }
// But instead of defining swap, you
// define a move assignment.
// Almost a swap, but it doesn't have to be.
X &operator=(X &&other) {
size = other.size;
std::swap(data, other.data);
return *this;
}
// The other implementations are just like
// copy-and-swap, except using moves instead.
X(X &&other): X() { *this = std::move(other); }
X &operator=(X const &other) { return *this = X{other}; }
// A swap is three moves, and implicit.
};
class Y {
private:
std::size_t mSize;
int* mArray;
void swap(Y& other) noexcept {
std::swap(this->mSize, other.mSize);
std::swap(this->mArray, other.mArray);
}
public:
Y(std::size_t size = 0):
mSize(size), mArray(mSize ? new int[mSize]() : nullptr) {}
Y(const Y& other):
mSize(other.mSize),
mArray(mSize ? new int[mSize] : nullptr) {
std::copy(other.mArray, other.mArray + mSize, mArray);
}
Y(Y&& other): Y() {
swap(other);
}
Y& operator=(Y& rhs) {
Y temp(rhs);
swap(temp);
return *this;
}
Y& operator=(Y&& rhs) {
swap(rhs);
return *this;
}
virtual ~Y() {
delete[] mArray;
}
};
// Constructor.
static void constructor_X(benchmark::State& state) {
while (state.KeepRunning()) {
X{};
}
}
static void constructor_Y(benchmark::State& state) {
while (state.KeepRunning()) {
Y{};
}
}
BENCHMARK(constructor_X);
BENCHMARK(constructor_Y);
// And construction assignment. This should be *exactly* the same as the prior.
static void assign_initialize_X(benchmark::State& state) {
while (state.KeepRunning()) {
X _ = X{};
}
}
static void assign_initialize_Y(benchmark::State& state) {
while (state.KeepRunning()) {
Y _ = Y{};
}
}
BENCHMARK(assign_initialize_X);
BENCHMARK(assign_initialize_Y);
// Now including copy construction!
static void copy_construct_X(benchmark::State& state) {
X tmp;
while (state.KeepRunning()) {
X{tmp};
}
}
static void copy_construct_Y(benchmark::State& state) {
Y tmp;
while (state.KeepRunning()) {
Y{tmp};
}
}
BENCHMARK(copy_construct_X);
BENCHMARK(copy_construct_Y);
// ...and copy assignment.
static void copy_assign_X(benchmark::State& state) {
X val;
X tmp;
while (state.KeepRunning()) {
val = tmp;
}
}
static void copy_assign_Y(benchmark::State& state) {
Y val;
Y tmp;
while (state.KeepRunning()) {
val = tmp;
}
}
BENCHMARK(copy_assign_X);
BENCHMARK(copy_assign_Y);
// Move construction too.
// This includes reassignment to keep things simpler.
static void move_construct_X(benchmark::State& state) {
X tmp;
while (state.KeepRunning())
tmp = X{std::move(tmp)};
}
static void move_construct_Y(benchmark::State& state) {
Y tmp;
while (state.KeepRunning())
tmp = Y{std::move(tmp)};
}
BENCHMARK(move_construct_X);
BENCHMARK(move_construct_Y);
// And move assignment!
static void move_assign_X(benchmark::State& state) {
X val;
X tmp;
while (state.KeepRunning()) {
val = std::move(tmp);
tmp = std::move(val);
}
}
static void move_assign_Y(benchmark::State& state) {
Y val;
Y tmp;
while (state.KeepRunning()) {
val = std::move(tmp);
tmp = std::move(val);
}
}
BENCHMARK(move_assign_X);
BENCHMARK(move_assign_Y);
BENCHMARK_MAIN()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment