2012-07-10 80 views
3

您好Stackoverflow社区。haskell编写大字符串

我relativly新Haskell和我注意到编写大型字符串文件与 writeFilehPutStr是缓慢的极端。

对于1.5 Mb字符串,我的程序(使用ghc编译)需要大约2秒,而C++中的 “相同”代码只需要大约0.1秒。 该字符串从包含约10000个元素的列表中生成,然后与writeFile一起转储。我也尝试遍历mapM_hPutStr的列表,结果相同。

有没有写一个大的字符串更快的方法?

更新

由于@applicative指出,下面的代码与2MB的文件完成在任何时间

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

所以我的问题似乎是在其他地方。这里是我的两个实现了 编写列表(词汇索引和CoordList是一个地图和列表类型别名)

与hPutStrLn

-- 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" 

也是跟WriteFile

-- Print to File 
indexToFile :: String -> WordIndex -> IO() 
indexToFile filename index = writeFile filename (indexToString "" index) 

-- Index to String 
indexToString :: String -> WordIndex -> String 
indexToString lead index = Map.foldrWithKey (\k v r -> lead ++ (entryToString k v) ++ r) "" index 

也许你们能帮助我在这里找到了一点加速。

在此先感谢

+0

什么样的内容有串? 'ByteString'的写入速度非常快,所以如果你能够廉价地转换成'ByteString',那将是一个选择。 – 2012-07-10 19:41:10

+2

我不相信写文件与它有任何关系; 'main = readFile“1.5mb.txt”>> = writeFile“1.5mb2.txt”'需要'0m0。089s',而不是2秒,因此比你为C++报告的要快。在大约50 MB时它开始接近2秒;同样'writeFile“big.txt”(show [1..250000])需要0.06秒,并产生一个1.6 MB的文件。 – applicative 2012-07-10 20:43:54

+0

你是对的@applicative我的问题似乎是在别的地方。我会发布一些代码 – 2012-07-10 21:06:47

回答

2

是的。你可以,例如,从模块Data.TextData.Text.Lazy使用Text类型,以更有效的方式(即UTF-16),比个字符的名单做内部表示文本。

当写入二进制数据(其可以或者可以不包含在某种形式的编码文本),可以使用ByteString S或它们的懒惰等同物。

在修改TextByteStrings时,在惰性版本上修改它们的某些操作会更快。如果你只想在创建它之后从这样的字符串读取,通常可以推荐非惰性版本。

2

这是众所周知的问题。默认哈斯克尔String类型是简单[Char]是通过定义慢,如果是懒洋洋地构造是死的慢(通常情况下)。然而,作为列表,它允许使用列表组合器进行简单和干净的处理,并且在性能不成问题时非常有用。如果是,则应使用ByteStringText程序包。 ByteString更好,因为它与ghc一起发货,但不提供unicode支持。 ByteString基于utf8的软件包可用于hackage。