我有以下程序將6位ASCII轉換爲二進制格式。GHC生成冗餘核心操作
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
這產生以下核心段:
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 }
通知,ord . chr == id
等方面存在是多餘的操作這裏:narrow8Word# (int2Word# (ord# (chr# wild2)))
是否有一個原因GHC被不必要地從int轉換 - > Char - > Int,或者這是一個糟糕的代碼生成的例子?這可以優化出來嗎?
編輯:這是使用GHC 7.4.2,我還沒有嘗試編譯與任何其他版本。我後來發現問題仍然存在於GHC 7.6.2中,但冗餘操作在github的當前HEAD分支中被刪除。
是的,確切地說。這些大多數都是價值層面的噪聲,只存在於改變類型。由於Core是鍵入的,所以這是必需的。 – 2013-02-26 19:19:22