2010-05-12 6 views
17

Let sagen, dass ich eine switch-Anweisung haben, wie untenKann die Reihenfolge der Fälle in Switch-Anweisungen die Leistung variieren?

switch(alphabet) { 

    case "f": 
     //do something 
     break; 

    case "c": 
     //do something 
     break; 

    case "a": 
     //do something 
     break; 

    case "e": 
     //do something 
     break; 

} 

Jetzt nehme ich an, dass die Frequenz Alphabet e mit der höchsten jeweils durch a, c und f folgt. Also, ich umstrukturiert nur die case Anweisung um und machte sie wie folgt:

switch(alphabet) { 

    case "e": 
     //do something 
     break; 

    case "a": 
     //do something 
     break; 

    case "c": 
     //do something 
     break; 

    case "f": 
     //do something 
     break; 
} 

Wird die zweite switch Aussage schneller sein als die erste switch Aussage? Wenn ja, und wenn in meinem Programm ich diese switch Anweisung viele Male nennen muss, wird das eine wesentliche Verbesserung sein? Oder wenn nicht, wie kann ich mein Frequenzwissen nutzen, um die Leistung zu verbessern?

+3

Sollten Sie nicht einfach die klarste Art und Weise schreiben, wie Sie es wissen, Profile mit realen Szenarien erstellen und optimieren, wo Sie es brauchen? –

Antwort

20

Nicht so sehr, dass Sie besorgt sein sollten. Es ist sicherlich nicht etwas, das vorhergesagt werden kann.

Mit Zeichenfolgenbeschriftungen verwendet der Compiler tatsächlich eine interne Hashtabelle, die die Zeichenfolgen Indizes in einer Sprungtabelle zuordnet. Die Operation ist also tatsächlich O (1) - unabhängig von der Anzahl der Labels.

Für Integer-Etiketten, dann glaube ich, dass der tatsächliche Code, der generiert wird, von der Anzahl der Etiketten abhängt und ob die Nummern aufeinander folgen (oder "fast" aufeinander folgen). Wenn sie aufeinanderfolgend sind (1, 2, 3, 4, ...), werden sie einfach in einen Sprungtisch umgewandelt. Wenn es viele davon gibt, wird die Hashtable + Jump-Tabelle (wie bei Strings) verwendet. Wenn es nur ein paar Labels gibt und diese nicht sofort in eine Sprungtabelle umgewandelt werden, wird nur dann in eine Reihe von if..then..else Statements umgewandelt.

Im Allgemeinen sollten Sie jedoch Code schreiben, so dass Sie lesen können, nicht so, dass der Compiler "schneller" Code produzieren kann.

(Beachten Sie meine obige Beschreibung ist eine Implementierung Detail, wie der C# -Compiler arbeitet intern: Sie nicht darauf immer arbeiten wie sich verlassen sollte - in der Tat könnte es nicht einmal genau arbeiten wie die jetzt , aber es ist zumindest die allgemeine Idee).

+0

+1: Genau das, was ich sagen wollte. Diese sind als GOTOs implementiert (überprüfen Sie den Reflektor, um zu verifizieren). Es ist O (1) - Sie sollten sich wirklich nicht um die Optimierung an diesem Punkt kümmern ... – Khanzor

+2

Was ist mit allen -1? –

+3

+1 von mir. Wenn perf ** wirklich ein Problem ist, sollten Sie eine Sprache verwenden, die näher am Metall sitzt. –

-1

Ich denke, die Art und Weise Schalter Fall ist es Schleife über alle Fälle von oben nach unten, um eine Übereinstimmung zu finden. Wenn es übereinstimmt, hört es dort auf.

Also, wenn Sie Änderungen vorgenommen haben, um die Häufigkeit Fälle priorisieren, ist die Antwort ja, kann es irgendwie mit der Leistung helfen. Aber ich glaube, dass es nicht viel helfen wird.

1

Sie haben die gleiche Leistung für einen relativ kleinen Satz von Werten. Ich habe versucht, den Assembler-Code von C-Programm zu überprüfen, bevor der Compiler eine Sprungtabelle aus allen Werten erstellt, die Sie in Ihrer switch-Anweisung haben.

Aber wenn die Fallwerte zu viele sind, ist es eine sichere Wette, dass sie zu ifelse if degenerieren werden, würde also Ihr Fall "E" auf die Oberseite beschleunigen würde sicherlich Dinge beschleunigen.

Es ist auch applicable in C#, C# erzeugt auch eine Sprungtabelle für Schaltanweisungen mit einem kleinen Satz, wenn auch nur für benachbarte Werte. Es ist also O (1), es gibt keine Mehrfachprüfung, auch wenn die ersten Werte nicht übereinstimmen.

2

Es hängt davon ab, wie der Compiler die switch-Anweisung implementiert.

Erstens, Sie können die Reihenfolge nicht beliebig vertauschen; Wenn Sie einen Fallblock in einer C-ähnlichen Sprache haben (C, C++, C#, Java, ...), und dieser Fallblock nicht in Pause beendet, können Sie die Fälle nicht wegen der Abwesenheit von neu anordnen Die Unterbrechung bedeutet, dass der Compiler den Fall bis zum nächsten Fall implementieren muss. Wenn wir diese spezielle Situation ignorieren, können Sie den Rest der Fälle permutieren. Wenn die Anzahl der Fälle klein ist, kann der Compiler die Falltests durch eine Sequenz von Vergleichen implementieren. Wenn die Anzahl der Fälle moderat ist, kann es einen ausgeglichenen binären Baum aus den Fällen konstruieren. Wenn die Anzahl der Fälle groß ist, implementieren die meisten Compiler eine indizierte Verzweigung für den Switch-Wert, wenn sie von eine dichte Menge ist. Wenn Teile der Menge der Fallwerte dicht sind und Teile nicht sind, kann der Compiler die Fälle in Gruppen unter Verwendung eines binären Baums partitionieren, um auszuwählen, welche dichte Menge und ein indizierter Sprung innerhalb der dichten Menge. (In der Tat kann der Compiler technisch alles tun, die Kontrolle an die entsprechenden Fall übergibt, aber meistens ist es einer der oben genannten).

Sie können sehen, dass die Reihenfolge von Bedeutung sein kann oder auch nicht, je nachdem, wie der Compiler den Switch implementiert. Für die meisten guten Compiler spielt das keine Rolle.

+1

Aus Gründen der Klarheit ist die Frage mit C# markiert, und C# unterstützt keine Fall Fälle wie im ersten Absatz beschrieben hier (jeder Fall muss mit 'break' oder' return' beendet werden. – Dusty

+0

Interessant. So wird in C# unnötigerweise "Pause" programmiert (siehe Beispiel OP). Ändert meine Antwort nicht wirklich viel. –

+0

Nein, C# ist in diesem Fall etwas ausführlich, Sie müssen den Fallblock explizit beenden. "break" (oder "return") ist erforderlich (vermutlich, um Fall-Through-Fälle zu verhindern, die zu einer bahnbrechenden Änderung werden, sollten sie in Zukunft umgesetzt werden). Und ich stimme zu, Ihre Antwort ist immer noch richtig und nützlich. – Dusty

Verwandte Themen