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