I've created a lightweight class with a constructor that takes around 10 parameters. The class does not change the parameter values; it just stores the values locally via the constructor.
Some parameters are reference types (strings, classes) and others are value types (int, bool, enums).
My question is should I pass all parameters (except the classes) via reference, i.e., using the keyword ref
?
My consideration here is performance.
As a rule of thumb, passing by reference or pointer is typically faster than passing by value, if the amount of data passed by value is larger than the size of a pointer.
Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument.
Call by Value uses extra space for formal parameters and making Call by Reference more memory efficient. Since no copies are being made in Call by Reference, it is faster than Call by Value.
Definition. Pass by value refers to a mechanism of copying the function parameter value to another variable while the pass by reference refers to a mechanism of passing the actual parameters to the function. Thus, this is the main difference between pass by value and pass by reference.
Only use ref
if the method needs to alter the parameters, and these changes need to be passed onto the calling code. You should only optimize this if you have run it through a profiler and determined that the bottleneck is indeed the CLR copying the method parameters onto the stack.
Bear in mind the CLR is heavily optimized for calling methods with parameters, so I shouldn't think this would be the issue.
I found on high volume function calls for larger value types that passing by ref was quicker, slightly. If you have a high volume of function calls and need speed this might be a consideration. I'm open to alternative evidence.
public static void PassValue(decimal value) { } public static void PassRef(ref decimal value) { } decimal passMe = 0.00010209230982047828903749827394729385792342352345m; for (int x = 0; x < 20; x++) { DateTime start = DateTime.UtcNow; TimeSpan taken = new TimeSpan(); for (int i = 0; i < 50000000; i++) { PassValue(passMe); } taken = (DateTime.UtcNow - start); Console.WriteLine("Value : " + taken.TotalMilliseconds); start = DateTime.UtcNow; for (int i = 0; i < 50000000; i++) { PassRef(ref passMe); } taken = (DateTime.UtcNow - start); Console.WriteLine("Ref : " + taken.TotalMilliseconds); }
Results:
Value : 150 Ref : 140 Value : 150 Ref : 143 Value : 151 Ref : 143 Value : 152 Ref : 144 Value : 152 Ref : 143 Value : 154 Ref : 144 Value : 152 Ref : 143 Value : 154 Ref : 143 Value : 157 Ref : 143 Value : 153 Ref : 144 Value : 154 Ref : 147 Value : 153 Ref : 144 Value : 153 Ref : 144 Value : 153 Ref : 146 Value : 152 Ref : 144 Value : 153 Ref : 143 Value : 153 Ref : 143 Value : 153 Ref : 144 Value : 153 Ref : 144 Value : 152 Ref : 143
No. For reference types, you are passing a reference already, there is no need to pass the reference by reference unless you want to change what the reference points to, e.g. assign it a new object. For value types, you can pass by reference, but unless you have a performance problem, I wouldn't do this. Especially if the types in question are small (4 bytes or less), there is little or no performance gain, possibly even a penalty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With