Skip to content

Instantly share code, notes, and snippets.

@apocelipes
Created June 1, 2021 19:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apocelipes/2f51ac6749d0923d02f4bb752a786064 to your computer and use it in GitHub Desktop.
Save apocelipes/2f51ac6749d0923d02f4bb752a786064 to your computer and use it in GitHub Desktop.
a benchmark of copy and swap idiom in c++
#include <iostream>
#include <string>
#include <utility>
#include <benchmark/benchmark.h>
template <typename T>
class Matrix {
public:
Matrix(unsigned int _x, unsigned int _y)
: x{_x}, y{_y}
{
data = new T*[y];
for (auto i = 0; i < y; ++i) {
data[i] = new T[x]{};
}
}
Matrix(const Matrix &obj)
: Matrix{obj.x, obj.y}
{
for (int i = 0; i < y; ++i) {
for (int j = 0; j < x; ++j) {
data[i][j] = obj[i][j];
}
}
}
Matrix(Matrix &&obj) noexcept
: x{obj.x}, y{obj.y}, data{obj.data}
{
obj.x = 0;
obj.y = 0;
obj.data = nullptr;
}
~Matrix() noexcept
{
for (auto i = 0; i < y; ++i) {
delete [] data[i];
}
delete [] data;
}
Matrix& operator=(const Matrix &rhs)
{
if (&rhs == this) {
return *this;
}
for (auto i = 0; i < y; ++i) {
delete [] data[i];
}
delete [] data;
x = rhs.x;
y = rhs.y;
data = new T*[y];
for (auto i = 0; i < y; ++i) {
data[i] = new T[x];
for (auto j = 0; j < x; ++j) {
data[i][j] = rhs.data[i][j];
}
}
return *this;
}
Matrix &operator=(Matrix &&rhs) noexcept
{
for (auto i = 0; i < y; ++i) {
delete [] data[i];
}
delete [] data;
x = rhs.x;
y = rhs.y;
data = rhs.data;
rhs.x = 0;
rhs.y = 0;
rhs.data = nullptr;
return *this;
}
private:
unsigned int x = 0;
unsigned int y = 0;
T **data = nullptr;
};
template <typename T>
class Matrix2 {
public:
Matrix2(unsigned int _x, unsigned int _y)
: x{_x}, y{_y}
{
data = new T*[y];
for (auto i = 0; i < y; ++i) {
data[i] = new T[x]{};
}
}
Matrix2(const Matrix2 &obj)
: Matrix2{obj.x, obj.y}
{
for (int i = 0; i < y; ++i) {
for (int j = 0; j < x; ++j) {
data[i][j] = obj[i][j];
}
}
}
Matrix2(Matrix2 &&obj) noexcept
: x{obj.x}, y{obj.y}, data{obj.data}
{
obj.x = 0;
obj.y = 0;
obj.data = nullptr;
}
~Matrix2() noexcept
{
for (auto i = 0; i < y; ++i) {
delete [] data[i];
}
delete [] data;
}
friend void swap(Matrix2 &a, Matrix2 &b) noexcept
{
using std::swap;
swap(a.x, b.x);
swap(a.y, b.y);
swap(a.data, b.data);
}
Matrix2& operator=(const Matrix2 &rhs)
{
Matrix2 tmp{rhs};
swap(*this, tmp);
return *this;
}
Matrix2 &operator=(Matrix2 &&rhs) noexcept
{
Matrix2 tmp{std::forward<Matrix2>(rhs)};
swap(*this, tmp);
return *this;
}
private:
unsigned int x = 0;
unsigned int y = 0;
T **data = nullptr;
};
static void bench_Matrix_copy(benchmark::State &state)
{
for (auto _ : state) {
auto m = Matrix<std::string>{10, 20};
auto m2 = Matrix<std::string>{10, 20};
m2 = m;
}
}
BENCHMARK(bench_Matrix_copy);
static void bench_Matrix2_copy_and_swap(benchmark::State &state)
{
for (auto _ : state) {
auto m = Matrix<std::string>{10, 20};
auto m2 = Matrix<std::string>{10, 20};
m2 = m;
}
}
BENCHMARK(bench_Matrix2_copy_and_swap);
static void bench_Matrix_move(benchmark::State &state)
{
for (auto _ : state) {
auto m = Matrix<std::string>{10, 20};
auto m2 = Matrix<std::string>{10, 20};
m2 = std::move(m);
}
}
BENCHMARK(bench_Matrix_move);
static void bench_Matrix2_move_and_swap(benchmark::State &state)
{
for (auto _ : state) {
auto m = Matrix2<std::string>{10, 20};
auto m2 = Matrix2<std::string>{10, 20};
m2 = std::move(m);
}
}
BENCHMARK(bench_Matrix2_move_and_swap);
BENCHMARK_MAIN();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment