2

我编写了一个程序来分析包含文件的样本数据。目前,我的程序将样本读入一个列表,然后我对样本列表 ( [Float]) 执行进一步的分析/处理。

我对性能不太满意,我正在考虑使用数组而不是列表来获得更好的性能。我也在研究并行化我的实现,Data.Array.Repa看起来很有希望。

目前,从文件中读取是这样的:

  1. 我将所有样本读入一个ByteString, 使用hGet.
  2. 我知道每个样本由 3 个字节表示,所以我将s分组ByteString为 3 个的列表。ByteString
  3. 我将我的toFloat函数映射ByteString到 s 列表上以获取Floats 列表。

这导致[Float]我分析以获得所需的信息。

我想知道我应该在这个过程的哪个步骤开始使用数组。我首先想到的是使用该listArray函数将 my[Float]转换为浮点数组。我不确定,但这似乎不是最有效的方法。

是否可以Data.Array.Repa.fromFunction在步骤 2 之后立即使用构造数组并跳过中间[Float]?对于该功能,我可以使用类似的东西(map toFloat bsList)吗?分组后bsList的 s 列表在哪里。ByteString

或者有没有办法将样本直接读入数组?

4

1 回答 1

1

Repa 实际上能够将 ByteString 作为数组的后端进行操作。因此,您可以通过尝试以下方式开始并行处理 ByteString:

#!/usr/bin/env stack
-- stack runghc --package repa

import Data.ByteString as BS
import Data.Array.Repa as R
import Data.Array.Repa.Repr.ByteString as R

getFloatsArr :: ByteString -> Array D DIM1 Float
getFloatsArr bs = R.traverse strArr (\(Z :. n) -> Z :. (n `div` 3)) getFloat where
  strArr = R.fromByteString (Z :. BS.length bs) bs
  getFloat getWord8 (Z :. k) =
    toFloat (getWord8 (Z :. k*3)) (getWord8 (Z :. k*3+1)) (getWord8 (Z :. k*3+2))
  toFloat = undefined -- convert to `Float` from 3 `Word8`s

processFurther :: Array U DIM1 Float -> a
processFurther = undefined

main :: IO ()
main = do
  bs <- BS.readFile "file.txt"
  arr <- R.computeUnboxedP $ getFloatsArr bs
  processFurther arr
  return ()
于 2017-01-22T11:51:30.453 回答