Last active
December 29, 2024 03:08
-
-
Save alifahrri/108b549edd7fec5f5480c419539e4ec4 to your computer and use it in GitHub Desktop.
benchmark code
This file contains hidden or 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
| // run on https://quick-bench.com/ | |
| #include <vector> | |
| #include <tuple> | |
| #include <cmath> | |
| #include <type_traits> | |
| template <typename T> | |
| class Vector | |
| { | |
| using data_type = T; | |
| using buffer_type = std::vector<data_type>; | |
| using size_type = size_t; | |
| buffer_type buffer_; | |
| size_type size_; | |
| public: | |
| Vector(size_type size) | |
| { | |
| size_ = size; | |
| buffer_.resize(size); | |
| } | |
| Vector& operator=(const Vector& other) | |
| { | |
| size_ = other.size_; | |
| buffer_.resize(size_); | |
| for (size_t i=0; i<size_; i++) { | |
| buffer_[i] = other.buffer_[i]; | |
| } | |
| return *this; | |
| } | |
| Vector operator+(const Vector& other) const | |
| { | |
| Vector result(other.size_); | |
| for (size_t i=0; i<result.size_; i++) { | |
| result.buffer_[i] = this->buffer_[i] + other.buffer_[i]; | |
| } | |
| return result; | |
| } | |
| Vector operator*(const Vector& other) const | |
| { | |
| Vector result(other.size_); | |
| for (size_t i=0; i<result.size_; i++) { | |
| result.buffer_[i] = this->buffer_[i] * other.buffer_[i]; | |
| } | |
| return result; | |
| } | |
| const T& operator[](size_type i) const | |
| { | |
| return buffer_[i]; | |
| } | |
| T& operator[](size_type i) | |
| { | |
| return buffer_[i]; | |
| } | |
| size_type size() const | |
| { | |
| return size_; | |
| } | |
| }; | |
| struct Add | |
| { | |
| template <typename Lhs, typename Rhs> | |
| auto operator()(const Lhs& lhs, const Rhs& rhs) const noexcept | |
| { | |
| return lhs + rhs; | |
| } | |
| }; | |
| struct Mul | |
| { | |
| template <typename Lhs, typename Rhs> | |
| auto operator()(const Lhs& lhs, const Rhs& rhs) const noexcept | |
| { | |
| return lhs * rhs; | |
| } | |
| }; | |
| template <typename Op, typename...Operands> | |
| class Expr | |
| { | |
| static constexpr auto Arity = sizeof...(Operands); | |
| using OperandsType = std::tuple<const Operands&...>; | |
| OperandsType operands_; | |
| Op op_; | |
| public: | |
| Expr(const Op op, const Operands&...operands) | |
| : operands_(operands...) | |
| , op_(op) | |
| {} | |
| template <auto...Is> | |
| auto apply(size_t i, std::integer_sequence<size_t,Is...>) const | |
| { | |
| return op_(std::get<Is>(operands_)[i]...); | |
| } | |
| auto operator[](size_t i) const | |
| { | |
| return apply(i,std::make_integer_sequence<size_t,Arity>{}); | |
| } | |
| const auto& operands() const | |
| { | |
| return operands_; | |
| } | |
| auto size() const | |
| { | |
| // assume lhs size == rhs size | |
| return std::get<0>(operands_).size(); | |
| } | |
| }; | |
| template <typename T> | |
| class Vector2 | |
| { | |
| using data_type = T; | |
| using buffer_type = std::vector<data_type>; | |
| using size_type = size_t; | |
| buffer_type buffer_; | |
| size_type size_; | |
| public: | |
| Vector2(size_t size) | |
| { | |
| size_ = size; | |
| buffer_.resize(size); | |
| } | |
| template <typename Other> | |
| auto operator+(const Other& rhs) const | |
| { | |
| return Expr<Add,Vector2<T>,Other>(Add(),*this,rhs); | |
| } | |
| template <typename Other> | |
| auto operator*(const Other& rhs) const | |
| { | |
| return Expr<Mul,Vector2<T>,Other>(Mul(),*this,rhs); | |
| } | |
| const T& operator[](size_type i) const | |
| { | |
| return buffer_[i]; | |
| } | |
| T& operator[](size_type i) | |
| { | |
| return buffer_[i]; | |
| } | |
| size_type size() const | |
| { | |
| return size_; | |
| } | |
| template <typename Other> | |
| auto operator=(const Other& rhs) | |
| { | |
| assert( rhs.size() == this->size() ); | |
| for (size_t i=0; i<this->size(); i++) { | |
| (*this)[i] = rhs[i]; | |
| } | |
| return *this; | |
| } | |
| }; | |
| template <typename T> | |
| void assign_add(Vector<T>& out, const Vector<T>& lhs, const Vector<T>& rhs) | |
| { | |
| auto size = out.size(); | |
| for (size_t i=0; i<size; i++) { | |
| out[i] = lhs[i] + rhs[i]; | |
| } | |
| } | |
| #define N 1'000'000 | |
| static void VectorAddition(benchmark::State& state) { | |
| Vector<float> a(N), b(N), c(N); | |
| for (auto _ : state) { | |
| c = a + b; | |
| benchmark::DoNotOptimize(c); | |
| } | |
| } | |
| BENCHMARK(VectorAddition); | |
| static void VectorAdditionAssign(benchmark::State& state) { | |
| Vector<float> a(N), b(N), c(N); | |
| for (auto _ : state) { | |
| assign_add(c,a,b); | |
| benchmark::DoNotOptimize(c); | |
| } | |
| } | |
| BENCHMARK(VectorAdditionAssign); | |
| static void Vector2Addition(benchmark::State& state) { | |
| Vector2<float> a(N), b(N), c(N); | |
| for (auto _ : state) { | |
| c = a + b; | |
| benchmark::DoNotOptimize(c); | |
| } | |
| } | |
| BENCHMARK(Vector2Addition); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment