Some features are so easy to use that it’s tempting to use them all the time, potentially turning them into anti-features. C++ references fall into this category. After all, it’s so easy to just add an ampersand, possibly in combination with const, and voilà - we magically don’t need to copy those pesky values when passing them to other functions. Moreover, there isn’t even a syntactic difference between accessing values and references
Unfortunately, there is a difference under the hood:
After all, references are pointers and accessing them requires dereferencing, which will likely result in performance hit. Because of this, we usually end up creating overloads accepting values by reference or value depending on their size, so that large values are passed by reference and small ones - by value.
It’s doable, but involves significant amount of boilerplate and more importantly doesn’t communicate the reasoning behind choosing one type of passing over another. Fortunately, C++ has templates, so we can accomplish both tasks fairly easily by writing something like
std::conditional_t returns a value type for types smaller or equal to 8 and a const reference for larger types. Note, that 8 is used just for illustrative purposes and you are encouraged to use a different constant or computed constexpr based on performance measurements on specific hardware.
Because of this on x86_64 for
we get
Again, it’s probably not a good idea to pass doubles by reference on x86_64, but it’s easy to show an example for small values of sizeof threshold.
thanks for the post. What is the sizeof(double) on your machine?