Speaking of rainy days. From the coding standard:
When passing small, POD objects into functions, you should always pass them by value, not by reference.
Most experienced C++ coders, myself included, fall into the habit of always passing function parameters as const-references, e.g. "const Foo&". This is the right thing to do for complex objects (e.g. Array, String, etc), but when you pass a reference, it prevents the compiler from using a whole slew of optimisation techniques on the call-site. For example, it means that there's no way for the compiler to really know whether the function will modify the original value (via const_cast) or whether it will modify a memory address which is an offset from the location of the object.So, the best-practice advice from the guys who actually write the optimisers is: Always stick to pass-by-value if possible, and only use references if the price of calling the copy constructor is very high.
This is particularly true in the case of small objects whose overall size is actually not much bigger than the size of a pointer. Some juce classes which should always be passed by value include: Point, Time, RelativeTime, Colour, all of the CharPointer_XYZ classes, Identifier, ModifierKeys, JustificationType, Range, PixelRGB, PixelARGB.
(I suspect that even larger structures like Rectangle<int> and Rectangle<float> may benefit from this technique too, especially on 64-bit CPUs.. If anyone has the time to create benchmarks to find out for sure, let me know!)
(Ignore the nan)
The results are in ... it makes bugger all difference for a Rectangle.
ByReference min:308163 max: 326298 average: 314090 stddev: 4702.17
ByValue min:271485 max: 582046 average: 328141 stddev: nan
FloatByValue min:352726 max: 383672 average: 363982 stddev: 8798.24
FloatByReference min:346290 max: 481381 average: 378697 stddev: 7714.52
This was calling a function in another object file, using the standard release build settings on Clang. A quick play with godbolt suggests that this changes entirely if you use GCC with concepts (I presume some non-standard standard extension??) where the registers are used for passing structs of four floats or ints (but not doubles).
