当以某种方式表达动作时,搜索文件需要永远

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当以某种方式表达动作时,搜索文件需要永远相关的知识,希望对你有一定的参考价值。

我有一个包含大约45k单词的文本文件,我想检查一些关于单词的简单属性。

这是我的程序的主体

import Data.Char
import Data.List
import qualified Data.Set as Set

vowel x = elem x "aeiou"

nontrivial w = not $ null [x | x <- w, vowel x]

toPigLatin :: String -> String
toPigLatin word
    | vowel (head word) = word ++ "ay"
    | otherwise = let (v, c) = span (not . vowel) word in
                                if c == "" then word
                                else c ++ v ++ "ay"


pigExists :: String -> Set.Set String -> Bool
pigExists word set = Set.member (toPigLatin word) set

但是有两种可能的方法来编写main动作:

main :: IO ()
main = do
    allWords <- words <$> readFile "/tmp/linuxwords2" --https://users.cs.duke.edu/~ola/ap/linuxwords
    let pigHits = filter (word -> nontrivial word && pigExists word (Set.fromList allWords)) allWords
    sequence_ $ map putStrLn pigHits

main :: IO ()
main = do
    allWords <- words <$> readFile "/tmp/linuxwords2" --https://users.cs.duke.edu/~ola/ap/linuxwords
    let pigHits = filter (word -> nontrivial word && pigExists word (Set.fromList allWords)) allWords
    putStrLn $ unlines pigHits

我尝试用ghc -O2编译,前者工作正常,但后者需要永远产生答案。

这两种风格之间真正的区别是什么?一般来说,我应该如何编写涉及IO的高效代码?

这个问题首先在Code Review SE中讨论过

答案

我可以在GHC 7.10.2中重现这个问题。使用GHC 8.2.2,问题不存在。解决方案:升级编译器。

看到第二个版本表现更差也就不足为奇了 - 毕竟它通过连接大量字符串来创建一个相当长的链表 - 这需要时间和内存。第一个版本不会以对putStrLn的许多(相对快速)调用为代价来制作中间列表。编辑:这并不是说它应该花这么长时间。我现在看到输出列表,我重定向到null,非常短。这肯定是旧GHC中的一个错误。

以上是关于当以某种方式表达动作时,搜索文件需要永远的主要内容,如果未能解决你的问题,请参考以下文章

当以编程方式设置根视图控制器时,导航和标签栏丢失

从动作返回文件时,流会被释放吗? [复制]

当以编程方式完成时,视图不会反映任何变化

scrollToPosition(),使用片段更新RecyclerView时

当以html格式下载时,IPython交互式小部件不会以图形方式更新

Relay.js 没有正确解析组合片段