Kann Haskell Inline-Funktionen als Argument übergeben werden?

8

Nehmen wir an, ich übergebe eine kleine Funktion f an map . Kann Haskell inline f mit map erzeugen, um eine kleine Imperativschleife zu erzeugen? Wenn ja, wie verfolgt Haskell, welche Funktion f wirklich ist? Kann das auch mit Arrow-Kombinatoren gemacht werden?

    
yong 29.08.2014, 10:32
quelle

3 Antworten

12

Wenn f als Argument übergeben wird, dann nein, wahrscheinlich nicht. Wenn f der Name einer Funktion auf oberster Ebene oder einer lokalen Funktion ist, dann wahrscheinlich yes.

%Vor%

Das heißt, ich nehme an, dass der größte Teil des Leistungsunterschieds zwischen Inline und Out-of-Line nicht von der eigentlichen Inlining selbst, sondern eher von eventuell nachfolgenden zusätzlichen Optimierungen herrührt.

Der einzige Weg, um "sicher" zu sein, besteht darin, den Code tatsächlich zu schreiben, ihn tatsächlich zu kompilieren und sich den Core anzusehen, der generiert wird. Und der einzige Weg zu wissen, ob es einen Unterschied macht (positiv oder negativ), ist das Benchmarking der Sache.

    
MathematicalOrchid 29.08.2014, 10:44
quelle
10

Die Definition der Haskell-Sprache schreibt keine Haskell-Implementierung für Inline-Code oder jegliche Art von Optimierung vor. Jede Implementierung ist frei, jede Optimierung anzuwenden, die sie für angemessen hält.

Haskell wird heutzutage oft mit GHC betrieben, was den Haskell-Code optimiert. Beim Inlining verwendet GHC einige Heuristiken, um zu entscheiden, ob etwas inline sein soll oder nicht. Der allgemeine Hinweis lautet, die Optimierung mit -O2 einzuschalten und die Ausgabe des Compilers zu überprüfen. Sie können den produzierten Core mit -ddump-simpl oder den Assemblycode mit -ddump-asm sehen. Einige andere Flags können ebenfalls nützlich sein.

Wenn Sie dann sehen, dass GHC keine Dinge in die Liste einfügt, die Sie gerne hätten, können Sie dem Compiler einen Hinweis mit {-# INLINE foo #-} und zugehörige Pragmas .

Seien Sie vorsichtig, wenn Sie gedankenlos Optimierungen anwenden. Häufig verbringen Programmierer ihre Zeit damit, Teile des Programms zu optimieren, die einen vernachlässigbaren Einfluss auf die Gesamtleistung haben. Um dies zu vermeiden, wird dringend empfohlen, Profil Dein Code zuerst, damit du weißt, wo dein Programm viel Zeit verbringt.

    
chi 29.08.2014 12:09
quelle
1

Hier ist ein Beispiel, in dem GHC eine Funktion als Argument übergeben hat:

%Vor%

plus wird als Argument von foldl1 übergeben, wodurch ein Vektor von ganzen Zahlen summiert wird. Im Core ist plus inline und optimiert für das ungeboxte GHC.Prim.+# :: Int# -> Int# -> Int# :

%Vor%

Das ist GHC.Prim.+# sc1_s757 y_a5Kg . Sie können die einfache artihmetic-Funktion plus hinzufügen und diesen Core-Ausdruck erweitern.

    
V. Semeria 06.09.2016 20:40
quelle

Tags und Links