ref performance

essamce 621 Reputation points
2020-12-16T12:18:54.143+00:00

hi
i want to know the pros and cons of using ref keyword in this particular case:

            void ReadDataFrom(ref SomeType x) // SomeType is not struct
            {
                // reading some date from x
            }

is ref in this case improves the performance ?
thanks in advance.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,166 questions
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 111.5K Reputation points
    2020-12-16T12:34:46.643+00:00

    In my opinion, if SomeType is a class and the function is ‘void ReadDataFrom(SomeType x)’, then x will be “a reference to SomeType object”. But if you add a ref, then x will be “a reference to a location that is a reference to SomeType object”. I do not think that such additional indirection increases the performance.

    In case of numbers, enumerations and strings, the indirection will not help too.

    Unless the optimising compiler reduces the redundant things.

    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Timon Yang-MSFT 9,571 Reputation points
    2020-12-17T02:32:33.847+00:00

    No, ref will not improve performance in this case.

    When we pass a reference type parameter, we are actually creating a copy of the object reference. There are two references pointing to the same object. We can modify the value of the object based on any one of the references, but these are all modifications to this object, and there is no change in the reference.

    But sometimes, we may want to assign a new object to the reference, which means that we are modifying the reference instead of the object. At this time, the reference in the method and the reference in the code calling this method no longer point to the same object, then the changes made in the method will not be reflected in the original code.

    After adding the ref keyword, the reference in the method is no longer a reference to an object, but a reference to a reference. Modifications based on this reference will be fully reflected in the original code.

    Simple example:

        class Program  
        {  
            static void Main(string[] args)  
            {  
                MyClass myClass = new MyClass() { ID = 1 };  
                Method1(myClass);  
                Console.WriteLine(myClass.ID);  
                Method2(ref myClass);  
                Console.WriteLine(myClass.ID);  
            }  
            public static void Method1(MyClass obj)  
            {  
                obj = new MyClass() { ID = 2 };  
            }  
            public static void Method2(ref MyClass obj)  
            {  
                obj = new MyClass() { ID = 3 };  
            }  
        }  
        class MyClass  
        {  
            public int ID { get; set; }  
        }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    2 people found this answer helpful.
    0 comments No comments

  2. Greg 1 Reputation point
    2023-10-29T01:32:25.89+00:00

    Hi, I find the details of that answer to be helpful, but I still think that we must mention the most important aspect regarding performance and that is to trust the compiler when appropriate. Consider the following example:

    string exampleStr = "Test";
    
    RefArgExample(ref exampleStr);
    
    // exampleStr is not needed after the above call to "RefArgExample", so the
    // compiler could optimize and reuse it inside the function.
    
    void RefArgExample(ref str) 
    {
    	// exampleStr passed as ref could be reused here and 
    	// a new object needn't	necessarily be created.
    	str = "Example string data";  
    }
    
    void NonRefArgExample(str) 
    {
    	// Do something with str.
    	// ...
    	// ...
    
    	// str cannot be reused, so a 2nd object must be
    	// created - unless the compiler optimizes.
    	var str = "Example string data";  
    }
    

    One might think that in some cases, passing an arg by ref can increase performance by eliminating the need to declare and create a new object in the function that accepts the ref arg. I.e. the ref arg serves as a no-cost local object. However, I think that even for non-ref args, a "smart" compiler could parse whether the passed arg is needed after the called function, and if not, could (under the hood) reuse the same string object inside the function rather than creating a new one.

    Importantly I also note, that for tiny "objects" such as int, the ref could cost more and reduce performance (unless used as an output parameter), but for large objects, the ref arg could increase performance, unless the compiler would optimize regardless.

    So, I think that what you are really telling us is to trust the compiler and use ref for what it is designed for, which is input-output parameters, and let the compiler engineers worry about the optimizations.