Ho il seguente programma per convertire ASCII a 6 bit in formato binario.GHC che genera operazioni core ridondanti
ascii2bin :: Char -> B.ByteString
ascii2bin = B.reverse . fst . B.unfoldrN 6 decomp . to6BitASCII -- replace to6BitASCII with ord if you want to compile this
where decomp n = case quotRem n 2 of (q,r) -> Just (chr r,q)
bs2bin :: B.ByteString -> B.ByteString
bs2bin = B.concatMap ascii2bin
Questo produce il seguente segmento di base:
Rec {
$wa
$wa =
\ ww ww1 ww2 w ->
case ww2 of wild {
__DEFAULT ->
let {
wild2
wild2 = remInt# ww1 2 } in
case leWord# (int2Word# wild2) (__word 1114111) of _ {
False -> (lvl2 wild2) `cast` ...;
True ->
case writeWord8OffAddr#
ww 0 (narrow8Word# (int2Word# (ord# (chr# wild2)))) w
of s2 { __DEFAULT ->
$wa (plusAddr# ww 1) (quotInt# ww1 2) (+# wild 1) s2
}
};
6 -> (# w, (lvl, lvl1, Just (I# ww1)) #)
}
end Rec }
notare che ord . chr == id
, e quindi v'è un funzionamento ridondante qui: narrow8Word# (int2Word# (ord# (chr# wild2)))
C'è una ragione GHC è inutilmente la conversione da Int - > Char -> Int, o si tratta di un esempio di scarsa generazione di codice? Questo può essere ottimizzato?
MODIFICA: utilizza GHC 7.4.2, non ho provato la compilazione con altre versioni. Da allora ho scoperto che il problema rimane in GHC 7.6.2, ma le operazioni ridondanti vengono rimosse nel ramo HEAD corrente su github.
Sì, proprio. La maggior parte di questi sono noop a livello di valore che esistono solo per cambiare tipo. Poiché Core è stato digitato, è necessario. –