2015-07-20 12 views
12

Ich habe in letzter Zeit irgendwo gelesen, dass Mustererkennung während der Laufzeit und nicht zur Kompilierzeit passiert. (Ich suche nach der Quelle, kann sie aber im Moment nicht finden.) Stimmt das? Und wenn ja, haben Wächter in Funktionen die gleiche Leistung?Ist Mustervergleich leistungsfähiger als Wächter?

Das zu lesen war für mich überraschend, weil ich dachte, dass GHC einige (wahrscheinlich nicht alle) Musterübereinstimmungsentscheidungen während der Kompilierungszeit optimieren konnte. Passiert das überhaupt?

Ein Fall zum Beispiel:

f 1 = 3 
f 2 = 4 

vs

f' a | a == 1 = 3 
    | a == 2 = 4 

Sie f und f' auf die gleiche Anzahl von Anweisungen (zum Beispiel in Kern und/oder niedriger) kompilieren?

Ist die Situation anders, wenn ich Mustervergleich auf einem Konstruktor anstelle eines Werts? Z.B. Wenn GHC erkennt, dass eine Funktion von einem Speicherort immer mit einem Konstruktor aufgerufen wird, optimiert es diesen Aufruf auf eine Weise, die die Laufzeitprüfung verhindert? Und wenn ja, können Sie mir ein Beispiel geben, das zeigt, was die Optimierung produziert?

Zusammengefasst

Was gut ist, über diese beiden Ansätze in Bezug auf Leistung wissen?

Wann ist eine Leistung vorzuziehen?

+4

Fragen Sie, wie Sie die Kernausgabe von GHC erhalten oder wie Sie Kriterien verwenden? – jberryman

+1

Relevant: [Haskell GHC: Wie hoch ist die zeitliche Komplexität einer Musterübereinstimmung mit N Konstruktoren?] (Http://stackoverflow.com/q/9027384/2751851) – duplode

+0

Ich würde eher denken, dass Mustervergleich schneller ist, wenn man bedenkt dass 'Eq'-Instanzen normalerweise auf einem Mustervergleich basieren. – AJFarmar

Antwort

14

Niemals Muster vs Wachen, können Sie auch über if vs case fragen.

Musterabgleich ist vorzuziehen zu Gleichheitsprüfungen. Die Gleichheitsprüfung ist in Haskell keine Selbstverständlichkeit. Boolean blindness ist ein Problem, aber abgesehen davon ist eine vollständige Gleichheitsprüfung oft einfach nicht möglich – z.B. unendliche Listen werden niemals gleich sein!

Wie viel effizienter die direkte Mustererkennung ist, hängt vom Typ ab. Im Fall von Zahlen, erwarten Sie keinen großen Unterschied, da diese Muster unter der Haube mit Gleichheitsprüfungen implementiert sind.

Ich bevorzuge in der Regel Muster –, weil sie nur schöner sind und kann effizienter sein. Gleichheitsprüfungen werden entweder genauso teuer oder möglicherweise teurer sein und sind nur unwissend. Benutze nur die boolesche Auswertung wenn du musst, ansonsten bleib bei den Mustern (die auch in guards sein können)!