2014-12-17 4 views
7

Вот это тестовая программа:Помощь GHC распаковывать в Int в равенстве на постоянной

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

А вот соответствующий бит ядра при компиляции с 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 { } 
    } 

Я интересно если совпадение по буквам 999999 действительно действительно самое эффективное, и если нет, то как я могу поощрить GHC превратить это в призыв к ==# или что-то в этом роде?

(Мое фактическое применение более активно)

ответ

8

На моей машине Ubuntu, соответствующий основной код компилируется в этом

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> 

первым, третьей линии, в основном equivalant к С кодом

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

Который является столь же оптимальным, как вы можете получить.

3

Это не имеет значения. При генерации кода case превратится в простое сравнение и условный переход. Это то, что всегда происходит для таких небольших выражений case. Есть определенные моменты, когда этот перевод ==# является неудачным, делая код, который имеет много слабо прогнозируемых ветвей, но это не относится к примеру, который вы даете.

Чтобы уточнить, я говорю о внутреннихcase.

+0

Упс, я пропустил внешний корпус. Это сделало мой ответ совершенно не относящимся к заданному вопросу. – Carl

+0

@ Карл, я не знаю, является ли это актуальным или нет для намерения вопроса! – dfeuer