Skip to content

Instantly share code, notes, and snippets.

@justbuchanan
Last active May 26, 2022 20:26
Show Gist options
  • Save justbuchanan/a1594aead5fda4e6e526 to your computer and use it in GitHub Desktop.
Save justbuchanan/a1594aead5fda4e6e526 to your computer and use it in GitHub Desktop.
Performance test of passing a small struct by value vs by reference in C++
#include <cmath>
#include <iostream>
using namespace std;
// Simple struct - should be the same size as a pointer on 64 bit machines.
class Point {
public:
Point(float xx = 0, float yy = 0) : x(xx), y(yy) {}
float x, y;
};
// A simple function that accepts the Point struct as a parameter. Change the
// template between a Point and a Point& to gauge performance differences. We
// force the compiler not to inline this function otherwise the benchmarks would
// be pretty worthless.
template <typename T>
__declspec(noinline) Point do_something(T pt) {
Point r;
r.x = pt.y * powf(pt.x, 2) / 8;
r.y = pt.x * sinf(pt.y) * 2;
return r;
}
int main(int argc, char **argv) {
constexpr long long num_iterations = 100000000;
Point sum;
for (long long i = 0; i < num_iterations; ++i) {
Point pt(i, i);
Point result = do_something<PARAM_TYPE>(pt);
sum.x += result.x;
sum.y += result.y;
}
// We print out the final result b/c otherwise the compiler is too smart and notices
// that we were looping for no result and makes the entire thing a no-op, ruining our benchmark.
cout << "final x: " << sum.x << endl;
return 0;
}
# Try changing the "-O3" flag to "-O2", "-O1", or removing it to compare performance under different compiler optimization levels.
CXX_FLAGS=-std=c++11 -O3
by-ref: main.cpp makefile
clang++ $(CXX_FLAGS) main.cpp -DPARAM_TYPE="Point&" -o ./by-ref
by-value: main.cpp makefile
clang++ $(CXX_FLAGS) main.cpp -DPARAM_TYPE="Point" -o ./by-value
compare: by-ref by-value
time ./by-ref
time ./by-value

Comparison of passing a small struct by value vs by reference in C++

Below are the results from running this on my 2011 MacBook Pro with an Intel Core i7-2635QM CPU @ 2.00GHz.

With no compiler optimizations turned on:

$ make compare
time ./by-ref
        7.07 real         7.05 user         0.00 sys
time ./by-value
        7.78 real         7.76 user         0.00 sys

With -O1

$ make compare
time ./by-ref
        2.55 real         2.54 user         0.00 sys
time ./by-value
        4.87 real         4.86 user         0.00 sys

With -O2

make compare
time ./by-ref
        1.79 real         1.78 user         0.00 sys
time ./by-value
        1.65 real         1.65 user         0.00 sys

With -O3

make compare
time ./by-ref
        1.77 real         1.76 user         0.00 sys
time ./by-value
        1.66 real         1.66 user         0.00 sys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment