2014-12-17 6 views
7

unbox:Hilfe GHC ein Int in Gleichheit auf eine konstanten

main = do 
    n <- fmap read $ getLine :: IO Int 
    if (999999 == n) then putStrLn "equal" else return() 

Und hier ist das entsprechende Bit des Kerns, wenn sie mit ghc --make -O2 -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings zusammengestellt:

case readEither6 @ Int (run @ Int main3 ipv1) of _ [Occ=Dead] { 
    [] -> case error @ Int readEither4 of wild1 { }; 
    : x ds1 -> 
    case ds1 of _ [Occ=Dead] { 
     [] -> 
     case x of _ [Occ=Dead] { I# ipv2 -> 
     case ipv2 of _ [Occ=Dead] { 
      __DEFAULT -> (# ipv,() #); 
      999999 -> hPutStr2 stdout main2 True ipv 
     } 
     }; 
     : ipv2 ipv3 -> case error @ Int readEither2 of wild2 { } 
    } 

Ich frage mich, Wenn die Groß-/Kleinschreibung auf dem Literal 999999 richtig ist, ist es hier die effizienteste Sache, und wenn nicht, wie kann ich GHC ermutigen, dies in einen Anruf zu ==# oder etwas umzuwandeln?

(Meine eigentliche Anwendung ist mehr beteiligt)

Antwort

8

Auf meinem Ubuntu-Box, die entsprechende kompilierte Kern-Code dieser zu

406168: 48 81 7b 07 3f 42 0f cmpq $0xf423f,0x7(%rbx) 
40616f: 00 
406170: 75 28     jne 40619a <c4fz_info+0x32> 
406172: bf 52 e3 6d 00   mov $0x6de352,%edi 
406177: be 90 65 6d 00   mov $0x6d6590,%esi 
40617c: 41 be 18 6a 6d 00  mov $0x6d6a18,%r14d 
406182: 48 83 c5 08    add $0x8,%rbp 
406186: e9 65 3c 00 00   jmpq 409df0 <base_GHCziIOziHandleziText_hPutStr2_info> 

Die ersten sind bis dritten Linie zum C-Code im Grunde equivalant kann

if (variable == 999999) { .... 

die etwa so optimal wie Sie ist bekommen.

3

Es wird keine Rolle. Bei der Codegenerierung wird case zu einem einfachen Vergleichs- und bedingten Sprung. Das passiert immer für so kleine case Ausdrücke. Es gibt definitiv Zeiten, in denen diese Übersetzung von ==# unglücklich ist, Code zu machen, der viele schlecht vorhergesagte Zweige hat, aber das gilt nicht für das Beispiel, das Sie geben.

Um zu verdeutlichen, ich spreche über die innerecase.

+0

Hoppla, ich habe den äußeren Fall verpasst. Das machte meine Antwort für die gestellte Frage völlig irrelevant. – Carl

+0

@Carl, ich weiß nicht, ob es relevant oder nicht in der Absicht der Frage ist! – dfeuer