如何在 Haskell 中有效地字节交换二进制数据
下面的 byteswap
可以满足我的要求,但我担心它对于较大的二进制数据块来说效率低下。有没有高效的库函数或者我可以使用的东西?
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as B (ByteString, length, append, cons, foldl)
byteswap :: B.ByteString -> B.ByteString
byteswap = let
swapper (collector, result) byte = let
updated = B.cons byte collector
in if 3 < B.length updated then ("", B.append result updated) else (updated, result)
in snd . B.foldl swapper ("", "")
main = print $ byteswap "1234abcdXYZ"
打印 4321dcba
。
byteswap
below does what I want, but I fear it is inefficient for larger chunks of binary data. Is there an efficient library function or something I can use?
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as B (ByteString, length, append, cons, foldl)
byteswap :: B.ByteString -> B.ByteString
byteswap = let
swapper (collector, result) byte = let
updated = B.cons byte collector
in if 3 < B.length updated then ("", B.append result updated) else (updated, result)
in snd . B.foldl swapper ("", "")
main = print $ byteswap "1234abcdXYZ"
Prints 4321dcba
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中最慢的部分是
append
,它与您生成的字节串的大小成线性关系,因此您的程序将至少花费二次时间。相反,您可以使用列表作为中间结构(理想情况下会被融合)并一次性打包整个结果:
这可以在我的机器上 3 秒内完成 1000 万字节。
您可以通过使用不安全的内部字节串函数来加速它:
并使用 我的 unsafePackLenBytes 融合补丁 我在 6 毫秒内交换了 1000 万字节。
The slow part of your code is
append
which is linear in the size of the bytestring that you are generating, hence your program will take at least quadratic time.Instead you can use a list as intermediate structure (which ideally would get fused away) and pack the whole result in one go:
This can do 10 million bytes in 3 seconds on my machine.
You can speed it up by using unsafe internal bytestring functions:
And with my patch for fusion of unsafePackLenBytes I get 10 million bytes swapped in 6 ms.