From 6b7e03b3dccf6d9906657d3749e7b89a9478126b Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 4 Feb 2025 02:11:55 -0500 Subject: [PATCH] adding the move assignment operator example --- hws/matrix_class/optimization/README.md | 40 +++++++++++++ hws/matrix_class/optimization/matrix_fast.cpp | 59 +++++++++++++++++++ hws/matrix_class/optimization/matrix_slow.cpp | 52 ++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 hws/matrix_class/optimization/README.md create mode 100644 hws/matrix_class/optimization/matrix_fast.cpp create mode 100644 hws/matrix_class/optimization/matrix_slow.cpp diff --git a/hws/matrix_class/optimization/README.md b/hws/matrix_class/optimization/README.md new file mode 100644 index 0000000..6645355 --- /dev/null +++ b/hws/matrix_class/optimization/README.md @@ -0,0 +1,40 @@ +Compile and Run these two programs to see the performance difference, note that the two programs have the same main function. + +Here are the results: + +```console +$ g++ matrix_fast.cpp -o matrix_fast +$ g++ matrix_slow.cpp -o matrix_slow +$ time ./matrix_fast + +real 0m1.134s +user 0m1.130s +sys 0m0.004s +$ time ./matrix_fast + +real 0m1.138s +user 0m1.134s +sys 0m0.004s +$ time ./matrix_fast + +real 0m1.139s +user 0m1.139s +sys 0m0.000s +$ time ./matrix_slow + +real 0m2.159s +user 0m2.159s +sys 0m0.000s +$ time ./matrix_slow + +real 0m2.161s +user 0m2.157s +sys 0m0.004s +$ time ./matrix_slow + +real 0m2.207s +user 0m2.200s +sys 0m0.000s +``` + +As can be seen, the fast version is much faster than the slow version, this is because it avoids many memory allocations/deallocations. diff --git a/hws/matrix_class/optimization/matrix_fast.cpp b/hws/matrix_class/optimization/matrix_fast.cpp new file mode 100644 index 0000000..5432ca7 --- /dev/null +++ b/hws/matrix_class/optimization/matrix_fast.cpp @@ -0,0 +1,59 @@ +#include +#include // For std::move + +class Matrix { +private: + int rows, cols; + int* data; // intentionally make this as an int* pointer, instead of int** pointer, + // so as to distinguish this example from the homework matrix class. + +public: + // default constructor + Matrix(){ + rows = 0; + cols = 0; + data = nullptr; + } + + // constructor + Matrix(int r, int c) : rows(r), cols(c) { + data = new int[r * c]; // allocate memory + // std::cout << "Constructor: Allocating memory\n"; + } + + // move assignment operator + // noexcept: this keyword tells the compiler and optimizer that this function will never throw an exception. + // The compiler may optimize code differently if it knows that the function will not throw exceptions. + Matrix& operator=(Matrix&& other) noexcept { + // std::cout << "Move Assignment Operator Invoked\n"; + if (this != &other) { + delete[] data; // free old memory + data = other.data; + rows = other.rows; + cols = other.cols; + + // leave `other` in a safe state + other.data = nullptr; + other.rows = 0; + other.cols = 0; + } + return *this; + } + + // destructor + ~Matrix() { + delete[] data; + // std::cout << "Destructor: Freeing memory\n"; + } +}; + +int main() { + // these lines mimic what is used in the BatchTest function. + Matrix* m_arr = new Matrix[5]; + for(int i=0; i<10000; i++){ + for(int j=0; j<10000; j++){ + m_arr[3] = Matrix(4,4); + } + } + delete [] m_arr; +} diff --git a/hws/matrix_class/optimization/matrix_slow.cpp b/hws/matrix_class/optimization/matrix_slow.cpp new file mode 100644 index 0000000..e81663a --- /dev/null +++ b/hws/matrix_class/optimization/matrix_slow.cpp @@ -0,0 +1,52 @@ +#include + +class Matrix { +private: + int rows, cols; + int* data; // intentionally make this as an int* pointer, instead of int** pointer, + // so as to distinguish this example from the homework matrix class. + +public: + // default constructor + Matrix(){ + rows = 0; + cols = 0; + data = nullptr; + } + + // constructor + Matrix(int r, int c) : rows(r), cols(c) { + data = new int[r * c]; // allocate memory + // std::cout << "Constructor: Allocating memory\n"; + } + + // assignment operator + Matrix& operator=(const Matrix& other) { + // std::cout << "Assignment Operator Invoked\n"; + if (this != &other) { + delete[] data; // free old memory + rows = other.rows; + cols = other.cols; + data = new int[rows * cols]; + } + return *this; + + } + + // destructor + ~Matrix() { + delete[] data; + // std::cout << "Destructor: Freeing memory\n"; + } +}; + +int main() { + // these lines mimic what is used in the BatchTest function. + Matrix* m_arr = new Matrix[5]; + for(int i=0; i<10000; i++){ + for(int j=0; j<10000; j++){ + m_arr[3] = Matrix(4,4); + } + } + delete [] m_arr; +}