我现在正在使用Haskell开发二进制解析程序。 我目前发现严格/懒惰的BitGet似乎都非常慢 令人惊讶地分配了大量的内存。
我测试了下面的代码(使用-O2构建),例如解析输入文件中的整个位,以及 找出分析结果。 在本例中,我使用了1,819,173字节的二进制文件。
严格版本:
import Prelude as P
import System.Environment (getArgs)
import Data.ByteString as B
import Data.Binary.Strict.BitGet
coreFunc :: Int -> BitGet Int
coreFunc len = f len 0
where
f 0 r = return r
f l _ = do
b <- getBit
f (l - 1) $ if b then 1 else 0
mainFunc :: B.ByteString -> IO ()
mainFunc bs =
case runBitGet bs (coreFunc ((B.length bs) * 8)) of
Left emsg -> error emsg
Right r -> print $ show r
main :: IO ()
main = do
args <- getArgs
case args of
[] -> return ()
(x:_) -> (do
bs <- B.readFile x
mainFunc bs
return ()
)
-- profiling result --
total time = 1.74 secs (1741 ticks @ 1000 us, 1 processor)
total alloc = 7,948,043,192 bytes (excludes profiling overheads)
懒人版:
import Prelude as P
import System.Environment (getArgs)
import Data.ByteString.Lazy as B
import Data.Binary.Bits.Get
import Data.Binary.Get
import Data.Int (Int64)
coreFunc :: Int64 -> BitGet Int
coreFunc len = f len 0
where
f 0 r = return r
f l _ = do
b <- getBool
f (l - 1) $ if b then 1 else 0
mainFunc :: B.ByteString -> IO ()
mainFunc bs = do
let r = runGet (runBitGet (coreFunc ((B.length bs) * 8))) bs
print $ show r
main :: IO ()
main = do
args <- getArgs
case args of
[] -> return ()
(x:_) -> (do
bs <- B.readFile x
mainFunc bs
return ()
)
-- profiling result --
total time = 2.21 secs (2207 ticks @ 1000 us, 1 processor)
total alloc = 6,405,531,680 bytes (excludes profiling overheads)
我想问一下:
答案 0 :(得分:2)
似乎您的coreFunc
应该跳过一些(len - 1)
位数,然后将一位读取为0
或1
并将其返回BitGet
monad。如果这是意图,那么这样的事情会更有效率。
我正在使用binary-bits
包:
import Control.Applicative
import Data.Binary.Get
coreFunc :: Int -> Get Int
coreFunc len =
fromEnum <$> runBitGet (block (skip (len - 1) *> bool)
skip :: Int -> BitGet ()
skip n = byteString bytes *> word64be bits *> pure ()
where (bytes, bits) = quotRem n 8 -- sizeOf Word8
不幸的是,程序包没有skip
函数让我们跳过n
位,它所基于的binary
包包含,所以我必须编写自己的。可以通过访问Block
内部来编写更高效的版本,但是库可能已经很好地优化了它,没有任何好处。
我想对您的版本进行基准测试以获得准确的比较,您能提供用于测试的二进制文件吗?