Hi all. Is there a way of implementing operator overloading for a struct such that I can only use references without having to apply the reference operator to intermediate values.
E.g. given a struct Vec3
I have implemented the various combinations of Vec3+&Vec3, Ve3+Vec3, &Vec3+Vec3, &Vec3 + &Vec3 (all returning a type Vec3)
And that allows me to do
a+bc
or even
&a+&b&c (ugly but readable).
But if I want to remove the non reference implementations then I will have to start adding additional brackets and an expression can quickly become unreadable!.
e.g
&a+&(&b*&c)
Is there a way to use references for performance without making things unreadable? Perhaps implementing a return of type &Vec3 which the compiler could choose to use where it can see the value is short lived?
Is Vec3just for example here? Because for a struct that small will usually get passed in registers. Plus, a function like adding two vectors is very likely to get inlined, making calling convention irrelevant altogether.
Categorically no, because there is no well-defined difference in performance between references and non-reference values to start with.
It's common to assume that accessing arguments by reference will be faster than accessing arguments by value, and for large arguments that assumption can even pay off, but it's worth measuring it before designing APIs around it. For small values - a struct consisting of three doubles or three integers, for example - the difference may be negligible, nonexistent, or even run the other direction.
In case of simple code operating on small structs all of it will probably get inlined and torn apart so that types don't exist any more.
However, in case of bigger non-inline functions references may even make code slower, because they will force writing objects out from registers to memory just to give them an address.
And the pointer indirection may even hurt optimizations if LLVM can't see how the pointer is used by other functions, and may end up re-reding the data it already has from memory again just in case some other function modified it.
References in Rust are used to control ownership. Don't force weird ownership out of unverified assumptions about performance.