gpt4 book ai didi

Haskell 解析数字行文件的更有效方法

转载 作者:行者123 更新时间:2023-12-02 18:35:42 27 4
gpt4 key购买 nike

所以我有一个大约 8mb 的文件,每个文件有 6 个由空格分隔的整数。

我当前的解析方法是:

tuplify6 :: [a] -> (a, a, a, a, a, a)
tuplify6 [l, m, n, o, p, q] = (l, m, n, o, p, q)

toInts :: String -> (Int, Int, Int, Int, Int, Int)
toInts line =
tuplify6 $ map read stringNumbers
where stringNumbers = split " " line

并映射到整数

liftM lines . readFile

这将返回一个元组列表。然而,当我运行它时,加载文件并解析它需要近 25 秒。有什么办法可以加快速度吗?该文件只是纯文本。

最佳答案

您可以使用 ByteString 来加快速度,例如

module Main (main) where

import System.Environment (getArgs)
import qualified Data.ByteString.Lazy.Char8 as C
import Data.Char

main :: IO ()
main = do
args <- getArgs
mapM_ doFile args

doFile :: FilePath -> IO ()
doFile file = do
bs <- C.readFile file
let tups = buildTups 0 [] $ C.dropWhile (not . isDigit) bs
print (length tups)

buildTups :: Int -> [Int] -> C.ByteString -> [(Int,Int,Int,Int,Int,Int)]
buildTups 6 acc bs = tuplify6 acc : buildTups 0 [] bs
buildTups k acc bs
| C.null bs = if k == 0 then [] else error ("Bad file format " ++ show k)
| otherwise = case C.readInt bs of
Just (i,rm) -> buildTups (k+1) (i:acc) $ C.dropWhile (not . isDigit) rm
Nothing -> error ("No Int found: " ++ show (C.take 100 bs))

tuplify6:: [a] -> (a, a, a, a, a, a)
tuplify6 [l, m, n, o, p, q] = (l, m, n, o, p, q)

运行速度相当快:

$ time ./fileParse IntList 
200000

real 0m0.119s
user 0m0.115s
sys 0m0.003s

对于 8.1 MiB 文件。

另一方面,使用 String 和转换(使用几个 seq 来强制计算)也只花费了 0.66 秒,因此大部分时间似乎不是花在解析上,而是花在处理结果上。

糟糕,错过了 seq,因此实际上并未针对 String 版本评估 read。解决这个问题,String + read 大约需要四秒,比使用 @Rotsor 评论中的自定义 Int 解析器的时间稍长一点

foldl' (\a c -> 10*a + fromEnum c - fromEnum '0') 0

因此解析显然确实花费了大量时间。

关于Haskell 解析数字行文件的更有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11319287/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com