Regex 使用正则表达式进行缓慢的文件解析

Regex 使用正则表达式进行缓慢的文件解析,regex,performance,haskell,Regex,Performance,Haskell,刚试着从pythonto-haskell重写平凡的文件解析器,但发现在同一台机器上,它的速度慢了15倍。用ghc-O2编译的代码 目标是计算正则表达式匹配的行数。 示例文本文件非常大,有几个Gib 代码如下: import Text.Regex.Posix import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BC filename = "sample.dat" mcount' ::

刚试着从pythonto-haskell重写平凡的文件解析器,但发现在同一台机器上,它的速度慢了15倍。用ghc-O2编译的代码

目标是计算正则表达式匹配的行数。 示例文本文件非常大,有几个Gib

代码如下:

import Text.Regex.Posix
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BC

filename = "sample.dat"

mcount' :: String -> [BS.ByteString] -> Int
mcount' sample file = foldr (\e acc -> if e =~ sample then acc+1 else acc) 0 file

main = do
    fcnt <- fmap BC.lines $ BS.readFile filename
    print $ mcount' "myregex" fcnt

如何显著提高性能?

最重要的事情似乎是从foldr切换到foldl。还有半打其他有用的优化,但这应该已经有了显著的改进。作为一般经验法则:

当要折叠的函数短路或使用保护递归时,请使用foldr。 否则使用foldl。 根本不要使用foldl。
最重要的事情似乎是从foldr切换到foldl’。还有半打其他有用的优化,但这应该已经有了显著的改进。作为一般经验法则:

当要折叠的函数短路或使用保护递归时,请使用foldr。 否则使用foldl。 根本不要使用foldl。
从foldr切换到foldl'。编译正则表达式可能会有所帮助。我不会把它作为一个答案,因为我还没有对它进行分析。哦,对于一个巨大的文本文件,你绝对应该使用Data.ByteString.Lazy[.Char8]。如果不需要的话,您不希望将整个多GB文件同时存储在内存中。@Daniel Wagner>将foldr切换到foldl'完成了任务!只是想了解在这种情况下foldl'的严格性的影响。正则表达式对于您的问题真的是必要的吗?Google regex现在您有两个问题:parsec库简单、干净、高效且类型安全。Text.regex.Posix包装了您的系统regex库,这可能与python完全不同。您可以尝试包装PCRE的Haskell库之一。从foldr切换到foldl’。编译正则表达式可能会有所帮助。我不会把它作为一个答案,因为我还没有对它进行分析。哦,对于一个巨大的文本文件,你绝对应该使用Data.ByteString.Lazy[.Char8]。如果不需要的话,您不希望将整个多GB文件同时存储在内存中。@Daniel Wagner>将foldr切换到foldl'完成了任务!只是想了解在这种情况下foldl'的严格性的影响。正则表达式对于您的问题真的是必要的吗?Google regex现在您有两个问题:parsec库简单、干净、高效且类型安全。Text.regex.Posix包装了您的系统regex库,这可能与python完全不同。您可以尝试一个包装PCRE的Haskell库。