Hello Stackoverflow社区。 p>
我是Haskell的新手,我注意到用一个文件写大字符串
<{1}}或writeFile
极其缓慢。
对于1.5 Mb字符串,我的程序(用ghc编译)大约需要2秒钟
c ++中的“相同”代码仅需约0.1秒。
该字符串是从包含大约10000个元素的列表生成的,然后使用hPutStr
转储。我还尝试使用writeFile
和mapM_
遍历列表并获得相同的结果。
是否有更快的方法来编写大字符串?
更新
正如@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"
也许你们可以帮助我一点点找到加速。
提前致谢
答案 0 :(得分:2)
是。例如,您可以使用模块Text
或Data.Text
中的Data.Text.Lazy
类型,它在内部以比Chars列表更有效的方式(即UTF-16)表示文本。
在编写二进制数据(可能包含或不包含以某种形式编码的文本)时,您可以使用ByteString
s或它们的惰性数据。
修改Text
或ByteStrings
时,在懒惰版本上修改它们的一些操作会更快。如果您只想在创建后读取这样的字符串,通常可以推荐使用非延迟版本。
答案 1 :(得分:2)
这是众所周知的问题。默认的Haskell String
类型是简单的[Char]
,并且根据定义很慢,如果它是懒惰地构建(通常情况),它会变慢。但是,作为列表,它允许使用列表组合器进行简单而干净的处理,并且在性能不是问题时非常有用。如果是,则应使用ByteString
或Text
个包。 ByteString
更好,因为它随ghc一起提供,但不提供unicode支持。基于ByteString
的utf8软件包可用于hackage。