我有以下程序需要一个大输入(扩展/ mime映射列表,文件列表)和逐行输出结果(每个文件的mime类型).
import System.IO
import Control.Monad
import qualified Data.Map as M
import System.FilePath
import Data.Char
main :: IO ()
main = do
input_line <- getLine
let n = read input_line :: Int -- Number of elements which make up the association table.
input_line <- getLine
let q = read input_line :: Int -- Number Q of file names to be analyzed.
mimeMap <- fmap M.fromList $ replicateM n $ do
input_line <- getLine
let input = words input_line
let ext = input!!0 -- file extension
let mt = input!!1 -- MIME type.
return (map toLower ext, mt)
replicateM_ q $ do
fname <- getLine
let ext = map toLower . drop 1 . takeExtension $ fname
mime = M.findWithDefault "UNKNOWN" ext mimeMap
putStrLn mime
Run Code Online (Sandbox Code Playgroud)
程序很慢,所以我开始分析它,我得到了一个奇怪的结果.
编译时
ghc --make -O2 coding.hs
Run Code Online (Sandbox Code Playgroud)
该计划非常缓慢.然而,-fprof-auto
似乎加快了这一切.编译
ghc --make -O2 coding.hs -prof -fprof-auto -fforce-recomp
Run Code Online (Sandbox Code Playgroud)
让它快速燃烧-prof
,没有任何影响.
奇怪的是,它在运行时也非常快runghc coding.hs
.
我不知道从哪里开始.有谁知道这里发生了什么?
编辑:我应该提到我的ghc是7.10.1.
提供问题的完整答案:
正如 Reid Barton 提到的,问题似乎是臭名昭著的状态黑客优化,它嵌入mimeMap
到重复的 IO 操作中,执行次数远远超过必要的次数。-fno-state-hack
禁用该优化并解决问题。解决该问题的另一种方法是强制对``mimeMap.
!mimeMap <- fmap M.fromList $ replicateM n [...]
Run Code Online (Sandbox Code Playgroud)
然而, GHC 7.10 中似乎也存在回归,但并-fno-state-hack
不能解决问题。这解释了为什么它没有为我解决这个问题。
非常感谢大家的回答。
归档时间: |
|
查看次数: |
216 次 |
最近记录: |