2015-07-12 7 views
10

Als Programmierer, die keine gute Idee über die .NET-Pipeline haben, habe ich mich gefragt, ob ref-Zeichenfolgen als Parameter für die Leistung in C# gut sind?Wird das Schlüsselwort 'ref' für Zeichenfolgenparameter in Methoden verwendet, die für die Leistung in C# geeignet sind?

Lassen Sie uns sagen, dass ich ein Verfahren wie dieses:

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

Wenn ich diese Methode verwenden, der Compiler eine Kopie des Textes für die Methode erstellt, nicht wahr?

Aber wenn ich das ref Stichwort:

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

.. Der Compiler sollte nur der Zeiger-Adresse des Text senden ...

So ist es gut für die Performance ref wie diese verwenden?

+4

Erzwingt zwei Speicherzugriffe statt einer, so dass es etwa doppelt so langsam ist. Nicht sehr wahrscheinlich können Sie diese Verlangsamung bemerken, da alles, was Sie mit der Saite machen, viel mehr Zeit in Anspruch nimmt. Benutze * ref * nicht unnötig. –

+1

Ich nehme an, OP ist verwirrt, weil in C++ Objekte, die als Wert übergeben werden, normalerweise kopiert werden. In C# ist dies nicht wahr, weil Objekte _ (standardmäßig) _ Referenzobjekte und nicht Wertobjekte sind. Wenn Sie 'struct's verwenden, werden Sie dem C++ - Verhalten etwas näher kommen, aber die Verwendung von' struct's ist in C# ziemlich selten. –

Antwort

21

Wenn ich diese Methode verwende, erstellt der Compiler eine Kopie des Textes für die Methode, richtig?

Nein, tut es nicht. string ist ein Referenztyp, und der Compiler erstellt eine neue Stapelvariable, die auf dieselbe string verweist, die an einer gegebenen Speicheradresse dargestellt wird. Es wird die Zeichenfolge nicht kopieren.

Wenn Sie ref für einen Referenztyp verwenden, wird keine Kopie des Zeigers auf die string erstellt. Es wird einfach die bereits erstellte Referenz übergeben. Dies ist nur dann sinnvoll, wenn Sie eine völlig neue string erstellen möchten:

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 ist es gut für die Leistung wie diese mit ref?

Die Leistungssteigerung ist nicht spürbar. Was passiert, ist, dass andere Entwickler verwirrt werden, warum Sie ref verwendet haben, um die Zeichenfolge zu übergeben.

+1

Nun, die Performance * Gewinne * werden offensichtlich nicht bemerkbar sein, denn in den besten Fällen wird es einfach nicht viel langsamer machen, es ist unmöglich es schneller zu machen. – Voo

+0

@Voo Auch wenn die 'Zeichenfolge' von' ref' übergeben wurde, wären die Vorteile gegenüber der eigentlichen Operation innerhalb der Methode vernachlässigbar und würden den Code weniger lesbar machen. Umso mehr Gründe, es nicht zu benutzen. –

+3

Mein Punkt ist, dass die Übergabe des Strings mit 'ref' den Code * langsamer * macht (marginal, da es nur ein single - cached - gelesen wird, aber trotzdem langsamer). Daher ist es irreführend, über Leistungszuwächse zu sprechen - höchstens wird es dadurch zu Leistungseinbußen kommen. – Voo