在Haskell中高效地解析ASCII文件

我想在 Haskell中重新实现一些我的ASCII解析器,因为我以为我可以获得一些速度.然而,即使一个简单的“grep和count”比 Python的一个恶作剧慢得多.

有人可以解释一下为什么以及如何正确执行?

所以任务是计算以字符串“foo”开头的行.

我的基本Python实现:

with open("foo.txt",'r') as f:
    print len([line for line in f.readlines() if line.startswith('foo')])

和Haskell版本:

import System.IO 
import Data.List

countFoos :: String -> Int
countFoos str = length $filter (isPrefixOf "foo") (lines str)

main = do
    contents <- readFile "foo.txt"
    putStr (show $countFoos contents)

运行时间在一个〜600MB的文件与17001895行显示,Python实现几乎比Haskell一个快四倍(运行在我的MacBook Pro Retina 2015与PCIe SSD):

> $time ./FooCounter                                                           
1770./FooCounter  20.92s user 0.62s system 98% cpu 21.858 total

> $time python foo_counter.py                                                   
1770
python foo_counter.py  5.19s user 1.01s system 97% cpu 6.332 total

与unix命令行工具相比:

> $time grep -c foo foo.txt                                                     
1770
grep -c foo foo.txt   4.87s user 0.10s system 99% cpu 4.972 total

> $time fgrep -c foo foo.txt                                                     
1770
fgrep -c foo foo.txt  6.21s user 0.10s system 99% cpu 6.319 total

> $time egrep -c foo foo.txt                                                     
1770
egrep -c foo foo.txt  6.21s user 0.11s system 99% cpu 6.317 total

有任何想法吗?

更新:

使用AndrásKovács的实现(ByteString),我得到了半秒钟!

> $time ./FooCounter                                                                                                               
1770
./EvtReader  0.47s user 0.48s system 97% cpu 0.964 total

解决方法

我对以下解决方案进行了基准测试:
{-# LANGUAGE OverloadedStrings #-}

import qualified Data.ByteString.Char8 as B

main =
  print . length . filter (B.isPrefixOf "foo") . B.lines =<< B.readFile "test.txt"

text.txt是一个具有800万行的170 MB文件,一半的行以“foo”开头.我编译了GHC 7.10和-O2 -fllvm.

ByteString版本的运行时间为0.27秒,而原始版本的运行时间为5.16秒.

但是,严格的ByteString版本使用170 MB内存加载完整的文件.将导入更改为Data.ByteString.Lazy.Char8我有0.39秒运行时和1 MB内存使用.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


html5中section的用法
span标签和p标签的区别
jsp文件和html文件的区别是什么
span标签和div的区别
html颜色代码表大全
span标签的作用是什么
dhtml的主要组成部分包括什么
html编辑器哪个软件好用
span标签属于什么样式标签
html文件乱码怎么办
html怎么读取json文件
html文件打开乱码怎么恢复原状
html怎么链接外部css
html文件怎么保存到本地
html怎么链接css文件
html和css怎么连接
html和css怎么关联
html文件怎么保存到一个站点
html文件怎么写
html出现乱码怎么解决