2014-12-17 46 views
7

Oto program testowy:Pomaganie GHC unbox int w równości na stałym

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

I tu jest odpowiedni kawałek rdzenia gdy skompilowany z ghc --make -O2 -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings:

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 { } 
    } 

Zastanawiam jeśli sprawa pasuje do literału 999999 jest naprawdę najbardziej wydajną rzeczą, a jeśli nie, w jaki sposób mogę zachęcić GHC do przekształcenia tego w połączenie pod numer ==# czy coś takiego?

(Moje aktualne zastosowanie jest bardziej złożone)

Odpowiedz

8

Na moim polu Ubuntu, odpowiedni kod rdzeń skompilowany do tej

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> 

pierwszej do trzeciej linii są zasadniczo equivalant do kodu c

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

Który jest tak optymalne jak można otrzymać.

3

Nie będzie miało znaczenia. Podczas generowania kodu ten case zamieni się w proste porównanie i skok warunkowy. Tak się zawsze dzieje w przypadku tak małych wyrażeń case. Zdarzają się przypadki, kiedy to tłumaczenie ==# jest niefortunne, tworząc kod, który ma dużo słabo przewidywanych gałęzi, ale to nie ma zastosowania do podanego przykładu.

Aby wyjaśnić, mówię o wewnętrznymcase.

+0

Ups, brakowało mi zewnętrznej obudowy. To sprawiło, że moja odpowiedź była zupełnie nieistotna dla zadanego pytania. – Carl

+0

@Carl, nie wiem, czy jest to istotne, czy nie, jeśli chodzi o cel pytania! – dfeuer