2012-04-19 6 views
8

Ich arbeite an einer C# .NET-Anwendung, die einige ziemlich komplexe wissenschaftliche Formeln auf großen Datensätzen verwendet (10 Millionen Datenpunkte im Durchschnitt). Ein Teil von dem, was ich tue, erfordert, die Formelimplementierungen so gut wie möglich zu optimieren.Ist die goto-Anweisung in C# langsam?

Mir ist aufgefallen, dass eine Formelimplementierung goto verwendet, und das hat mich gefragt: Geht das langsamer als andere Flusskontrollkonstrukte?

+4

bitte tun Sie sich einen Gefallen und verwenden Sie nicht in C#! – MUG4N

+3

@ MUG4N Es ist nichts falsch mit goto's ist, wie Sie sie verwenden, die sie böse macht – GETah

+0

@GETah Und sie werden so sehr selten verantwortungsvoll verwendet, und es gibt sehr wenig Wert bei der Verwendung von ihnen über die Alternativen, also warum die Risiken eingehen? – Servy

Antwort

11

ist langsamer als andere Flow-Control-Konstrukte?

Nein. Alle anderen Flow-Control-Konstrukte sind im Grunde goto sowieso.

+0

Danke. Nicht sicher, warum jemand meine Frage niedergeschrieben hat. – kevin628

+3

Es ist eine vollkommen vernünftige Frage. Die Leute reagieren nur viszeral, wenn sie etwas mit 'goto' zu tun haben. – jason

4

Die goto Anweisung in C# ist nicht langsamer als jedes andere Kontrollflusskonstrukt. Tatsächlich wird die überwiegende Mehrheit der Kontrollflusskonstrukte (wenn, während, für usw.) in Bezug auf goto implementiert.

Zum Beispiel:

if (someExpr) { 
    Console.WriteLine("here"); 
} 
Console.WriteLine("there"); 

ist im Wesentlichen auf die folgenden

gotoIf !someExpr theLabel; 
Console.WriteLine("here"); 
theLabel: 
Console.WriteLine("there"); 
zusammengestellt unten
1

if s und for sind goto s intern vom Compiler übersetzt, damit sie nicht am schnellsten sind als goto s

4

Ich bemerkte dass eine Formelimplementierung goto verwendet, und das machte mich frage mich: Ist goto langsamer als andere Flow-Control-Konstrukte?

goto ist nicht langsamer als jeder andere Flusskontrollmechanismus. Es wird, wie die meisten Flusskontrollmechanismen, in eine br.s (oder eine ähnliche) MSIL-Anweisung kompiliert. Es gibt jedoch Situationen, in denen goto etwas schneller sein kann. Sie sind meist auf Situationen beschränkt, in denen break und continue innerhalb von verschachtelten Schleifen verwendet werden. Betrachten Sie den folgenden Code.

bool condition = false; 
for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      condition = Evaluate(i, j, k); 
      if (condition) 
      { 
       // break out of everything 
      } 
     } 
    } 
} 

Es gibt verschiedene Möglichkeiten, wie Sie aus der ganzen Sache ausbrechen könnten. Hier ist eine Methode.

bool condition = false; 
for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      condition = Evaluate(i, j, k); 
      if (condition) break; 
     } 
     if (condition) break; 
    } 
    if (condition) break; 
} 

Das Problem ist, dass jede Schleife die condition Flag überprüfen muss. Wir könnten dies mit einem goto umgestalten, um es etwas effizienter und etwas eleganter zu machen.

for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      if (Evaluate(i, j, k)) goto BAILOUT; 
     } 
    } 
} 
BAILOUT: 
+2

+1 für das ausgezeichnete Beispiel, wenn goto die sauberste, am meisten wartbare Lösung ist. Ein anderes Beispiel ist Code mit vielen möglichen Fehlerbedingungen, die alle verwenden, um zu einem allgemeinen Fehlerausgang zu retten. –