performance - 如何在 Haskell 中有效地字节交换二进制数据

标签 performance haskell binaryfiles endianness

下面的

byteswap 做了我想要的,但我担心它对于较大的二进制数据 block 来说效率低下。是否有高效的库函数或我可以使用的东西?

{-# 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

最佳答案

您的代码中较慢的部分是append,它与您生成的字节串的大小成线性关系,因此您的程序至少需要二次方的时间。

相反,您可以使用列表作为中间结构(理想情况下会被融合掉)并一次性打包整个结果:

byteswap :: B.ByteString -> B.ByteString
byteswap xs = B.pack
  [ B.index xs $ i * 4 + j
  | i <- [0 .. B.length xs `quot` 4 - 1]
  , j <- [3,2,1,0]
  ]

这可以在我的机器上 3 秒内完成 1000 万字节。

您可以使用不安全的内部字节串函数来加快速度:

byteswap :: B.ByteString -> B.ByteString
byteswap xs = unsafePackLenBytes (B.length xs `quot` 4 * 4)
  [ unsafeIndex xs $ i * 4 + j
  | i <- [0 .. B.length xs `quot` 4 - 1]
  , j <- [3,2,1,0]
  ]

还有my patch for fusion of unsafePackLenBytes我在 6 毫秒内交换了 1000 万字节。

关于performance - 如何在 Haskell 中有效地字节交换二进制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71330483/

相关文章:

SQL 使用字符串函数提高索引列性能

haskell - 扩展 Data.Functor.Foldable 时遇到问题

haskell - 截断为 Word 类型

linux - Matlab 二进制文件不接受其在 shell 中的输入值

.net - 从 VB.Net 中的二进制文件中提取字符串

Javascript,在 React 应用程序中分配给函数组件中的 {},代码审查

android - AndEngine - 我是否尝试尽可能使用一点 map 集?

c++ - 具有 libaio 性能问题的 Linux 异步 IO

Haskell:解析命令行参数

c - sizeof(var) 在 C 语言中总是有效吗?