haskell写大字符串

时间:2012-07-10 19:29:40

标签: haskell

Hello Stackoverflow社区。

我是Haskell的新手,我注意到用一个文件写大字符串 <{1}}或writeFile极其缓慢。

对于1.5 Mb字符串,我的程序(用ghc编译)大约需要2秒钟 c ++中的“相同”代码仅需约0.1秒。 该字符串是从包含大约10000个元素的列表生成的,然后使用hPutStr转储。我还尝试使用writeFilemapM_遍历列表并获得相同的结果。

是否有更快的方法来编写大字符串?

更新

正如@applicative所指出的,下面的代码很快就会以2MB的文件结束

hPutStr

所以我的问题似乎在其他地方。这是我的两个实现 编写列表(WordIndex和CoordList是Map和List的typealiases)

使用hPutStrLn

main = readFile "input.txt" >>= writeFile "ouput.txt"

with writeFile

-- Print to File
indexToFile :: String -> WordIndex -> IO ()
indexToFile filename index =
    let 
        indexList = map (\(k, v) -> entryToString k v)  (Map.toList index)
    in do
        output <- openFile filename WriteMode
        mapM_ (\v -> hPutStrLn output v) indexList
        hClose output


-- Convert Listelement to String
entryToString :: String -> CoordList -> String
entryToString key value = (embedString 25 key) ++ (coordListToString value) ++ "\n"

也许你们可以帮助我一点点找到加速。

提前致谢

2 个答案:

答案 0 :(得分:2)

是。例如,您可以使用模块TextData.Text中的Data.Text.Lazy类型,它在内部以比Chars列表更有效的方式(即UTF-16)表示文本。

在编写二进制数据(可能包含或不包含以某种形式编码的文本)时,您可以使用ByteString s或它们的惰性数据。

修改TextByteStrings时,在懒惰版本上修改它们的一些操作会更快。如果您只想在创建后读取这样的字符串,通常可以推荐使用非延迟版本。

答案 1 :(得分:2)

这是众所周知的问题。默认的Haskell String类型是简单的[Char],并且根据定义很慢,如果它是懒惰地构建(通常情况),它会变慢。但是,作为列表,它允许使用列表组合器进行简单而干净的处理,并且在性能不是问题时非常有用。如果是,则应使用ByteStringText个包。 ByteString更好,因为它随ghc一起提供,但不提供unicode支持。基于ByteString的utf8软件包可用于hackage。