15

As a programmer who don't have a good idea about the .NET pipeline, I was wondering if using ref strings as parameters are good for performance in C#?

Let's say I have a method like this:

public int FindSomething(string text)
{
    // Finds a char in the text and returns its index
}

When I use this method, the compiler creates a copy of the text for the method, right?

But if I use the ref keyword:

public int FindSomething(ref string text)
{
    // Finds a char in the text and returns its index
}

.. the compiler should only send the text's pointer address...

So is it good for performance using ref like this?

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Ibrahim Ozdemir
  • 613
  • 1
  • 5
  • 18
  • 4
    It forces two memory accesses instead of one so it is about twice as slow. Not terribly likely you can notice that slowdown since whatever you do with the string itself tends to take a lot more time. Do not use *ref* needlessly. – Hans Passant Jul 12 '15 at 13:11
  • 1
    I assume OP is confused because, in C++, objects passed-by-value are usually copied. In C# this isn't true, because objects are _(by-default)_ reference-objects rather than value-objects. When using `struct`s you'll get something much closer to the C++ behavior, but using `struct`s is pretty rare in C#. – BlueRaja - Danny Pflughoeft Jul 12 '15 at 20:07

1 Answers1

27

When I use this method, the compiler creates a copy of the text for the method, right?

No, it doesn't. string is a reference type, and the compiler will create a new stack variable which points to the same string represented at a given memory address. It won't copy the string.

When you use ref on a reference type, there won't be a copy of the pointer to the string created. It will simply pass the already created reference. This is useful only when you want to create an entirely new string:

void Main()
{
    string s = "hello";
    M(s);
    Console.WriteLine(s);
    M(ref s);
    Console.WriteLine(s);
}

public void M(string s)
{
    s = "this won't change the original string";
}

public void M(ref string s)
{
    s = "this will change the original string";
}

So is it good for performance using ref like this?

The performance gains won't be noticeable. What will happen is other developers getting confused as to why you used ref to pass the string.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • 1
    Well the performance *gains* obviously won't be noticeable because in the best of all cases it just won't make it much slower, it's impossible to make it faster. – Voo Jul 12 '15 at 14:21
  • @Voo Even if the `string` was passed by `ref`, the benefits would be neglectable to the actual operation inside the method, and would make the code less readable. All the more reasons not to use it. – Yuval Itzchakov Jul 12 '15 at 14:27
  • 3
    My point is that passing the string by `ref` makes the code *slower* (marginally since it's only a single - cached - read, but slower nonetheless). Hence talking about performance gains is misleading - at most you won't see performance degradation by doing this. – Voo Jul 12 '15 at 14:28
  • strings are an unusual case since they are interned, so even if you technically got a new copy of the string, it would still actually be the same copy anyway. – Jason Coyne Jul 12 '15 at 15:48
  • Ok thanks for the answer but, i will ask the same question for the struct types. String is a reference type but according to [MSDN](https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx) structs are not. So lets say i have a big struct type, and i am passing this struct variable to lots of methods many many times. How can i avoid from .net to copy this variable every time i pass it (since those methods wont change the variable's content) – Ibrahim Ozdemir Feb 05 '17 at 00:04