我有一个程序使用haskell-src-exts,并提高性能我决定严格记录字段.这导致了更糟糕的表现.
这是我正在改变的完整模块:
{-# LANGUAGE DeriveDataTypeable, BangPatterns #-}
module Cortex.Hackage.HaskellSrcExts.Language.Haskell.Exts.SrcSpan(
SrcSpan, srcSpan, srcSpanFilename, srcSpanStartLine,
srcSpanStartColumn, srcSpanEndLine, srcSpanEndColumn,
) where
import Control.DeepSeq
import Data.Data
data SrcSpan = SrcSpanX
{ srcSpanFilename :: String
, srcSpanStartLine :: Int
, srcSpanStartColumn :: Int
, srcSpanEndLine :: Int
, srcSpanEndColumn :: Int
}
deriving (Eq,Ord,Show,Typeable,Data)
srcSpan :: String -> Int -> Int -> Int -> Int -> SrcSpan
srcSpan fn !sl !sc !el !ec = SrcSpanX fn sl sc el ec
instance NFData SrcSpan where
rnf (SrcSpanX x1 x2 x3 x4 x5) = rnf x1
Run Code Online (Sandbox Code Playgroud)
注意,构造a的唯一方法SrcSpan是使用srcSpan所有Ints中严格的函数.
使用此代码,我的程序(抱歉,我无法分享)运行在163s.
现在改变一行,例如,
, srcSpanStartLine :: !Int
Run Code Online (Sandbox Code Playgroud)
即,该srcSpanStartLine字段现在标记为严格.我的程序现在运行198秒.因此,严格控制一个字段会使运行时间增加约20%.
这怎么可能?srcSpan函数的代码应该是相同的,因为它已经是严格的.srcSpanStartLine选择器的代码应该更简单一些,因为它不再需要进行评估.
我已经尝试过-funbox-strict-fields,并-funbox-small-strict-field开启和关闭.它没有任何明显的区别.我正在使用ghc 7.8.3.
有没有人见过类似的东西?什么可能导致它的任何好主意?
aug*_*tss 15
通过一些更多的调查,我可以回答我自己的问题.简短的回答是单一的.
答案稍微长一些.在一个地方,我使用uniplate来获取a的孩子Pat(haskell-src-exts类型的模式).呼叫看起来像children p和本实例的类型children是Pat SrcSpanInfo -> [Pat SrcSpanInfo].所以它不进行递归,只返回节点的直接子节点.
Uniplate使用两种截然不同的方法,具体取决于操作类型中是否存在严格字段.如果没有严格的字段,它会很快合理,严格的字段会切换到使用状态gfoldl并且非常慢.即使我使用uniplate没有直接涉及严格的字段,它也放慢了速度.
结论:如果您在任何地方都有严格的视野,请注意提示!
| 归档时间: |
|
| 查看次数: |
526 次 |
| 最近记录: |