我编写了一个程序来分析包含文件的样本数据。目前,我的程序将样本读入列表,然后对样本列表([Float]
)执行进一步的分析/处理。
我对性能不太满意,我正在考虑使用Arrays而不是列表来获得更好的性能。我也在考虑并行化我的实现,Data.Array.Repa
看起来很有希望。
目前,从文件中读取的内容如下:
ByteString
将所有样本读入hGet
。ByteString
分组为ByteString
的3个列表。toFloat
函数映射到ByteString
列表中,以获取Float
的列表。 这导致我分析的[Float]
以获得所需信息。
我想知道在这个过程的哪一步我应该开始使用一个数组。我首先考虑使用listArray
函数将我的[Float]
转换为浮点数组。我不确定,但这似乎不是最有效的方式。
是否可以在步骤2之后使用Data.Array.Repa.fromFunction
构建数组并跳过中间[Float]
?对于该功能,我可以使用(map toFloat bsList)
之类的东西吗?其中bsList
是分组后ByteString
的列表。
或者有没有办法将样本直接读入数组?
答案 0 :(得分: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 ()