Haskell Bytestring到[Word16]的高效转换
我正在尝试从bytestring到Word16列表的简单转换。下面使用Data.Binary.Get的实现是可行的,尽管这是代码中的一个性能瓶颈。这是可以理解的,因为IO总是很慢,但我想知道是否有更有效的方法来做到这一点Haskell Bytestring到[Word16]的高效转换,haskell,bytestring,Haskell,Bytestring,我正在尝试从bytestring到Word16列表的简单转换。下面使用Data.Binary.Get的实现是可行的,尽管这是代码中的一个性能瓶颈。这是可以理解的,因为IO总是很慢,但我想知道是否有更有效的方法来做到这一点 getImageData' = do e <- isEmpty if e then return [] else do w <- getWord16be ws <- getImageData' r
getImageData' = do
e <- isEmpty
if e then return []
else do
w <- getWord16be
ws <- getImageData'
return $ w : ws
getImageData'=do
e我怀疑您在使用Data.Binary.Get
时遇到的最大问题是,解码器对于您的目的来说本质上太严格了。serialise
和其他序列化库似乎也是如此。我认为最根本的问题是,尽管您知道只要ByteString
的字节数为偶数,操作就会成功,但库并不知道这一点。因此,它必须通过testring阅读整个,然后才能得出“啊,是的,一切都很好”的结论,并构建您所请求的列表。事实上,按照构建结果的方式,它将在实际执行任何有用的操作之前构建大量闭包(数量与长度成比例)
你怎么能解决这个问题?直接使用bytestring
库即可。最简单的方法是使用解包
,但我认为您可能会获得更好的性能,如下所示:
{-# language BangPatterns #-}
module Wordy where
import qualified Data.ByteString as BS
import Data.ByteString (ByteString)
import Data.Word (Word16)
import Data.Maybe (fromMaybe)
import Data.Bits (unsafeShiftL)
toDBs :: ByteString -> Maybe [Word16]
toDBs bs0
| odd (BS.length bs0) = Nothing
| otherwise = Just (go bs0)
where
go bs = fromMaybe [] $ do
(b1, bs') <- BS.uncons bs
(b2, bs'') <- BS.uncons bs'
let !res = (fromIntegral b1 `unsafeShiftL` 8) + fromIntegral b2
Just (res : go bs'')
{-#语言模式}
模块Wordy在哪里
将符合条件的数据.ByteString作为BS导入
导入Data.ByteString(ByteString)
导入数据.Word(Word16)
导入数据。可能(来自可能)
导入数据位(unsafeShiftL)
toDBs::ByteString->Maybe[Word16]
toDBs bs0
|奇数(BS.length bs0)=无
|否则=仅(转到bs0)
哪里
go bs=fromMaybe[]$do
(b1,bs')这里没有IO。反序列化和它的性能是我对Haskell最初的烦恼之一。您可以在pureMD5包和word32反序列化中查找一种方法。