我有以下程序将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