Last active
March 1, 2016 10:55
-
-
Save Veedrac/8331ebd66781d51cccd5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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