当以某种方式表达动作时,搜索文件需要永远
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时