У меня есть программа, которая использует 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
Обратите внимание, что единственный способ построить SrcSpan
- это использовать функцию SrcSpan
, которая является строгой во всех Int
s.
С помощью этого кода моя программа (извините, я не могу ее разделить) работает в 163s.
Теперь измените одну строку, например
, srcSpanStartLine :: !Int
I.e., поле srcSpanStartLine
теперь отмечено как строгое. Моя программа теперь занимает 198 секунд. Поэтому, чтобы одно поле строго меняло время работы примерно на 20%.
Как это возможно? Код для функции SrcSpan
должен быть таким же, несмотря на то, что он уже строг. Код для селектора srcSpanStartLine
должен быть немного проще, поскольку его больше не нужно оценивать.
Я экспериментировал с -funbox-strict-fields
и -funbox-small-strict-field
вкл. и выкл. Это не делает заметной разницы. Я использую ghc 7.8.3.
Кто-нибудь видел что-то подобное? Любые яркие идеи, что может вызвать это?