

Tests - make sure you have tests, so you don't break anything while optimising.

- make sure you have tests, so you don't break anything while optimising.

Profile - if you don't profile first, you are almost certainly optimising the wrong thing.

- if you don't profile first, you are almost certainly optimising the wrong thing.

Necessity - only start the optimisation process if something is running too slowly.

- only start the optimisation process if something is running too slowly.

Benchmark - use a sensible and representative test case to benchmark, to make sure you optimise the right thing.

- use a sensible and representative test case to benchmark, to make sure you optimise the right thing.

Optimising - to make a function faster, either call it less, or write it better.



Rational

Int

Either String [Int]

Int

String

undefined

data Foo = Foo !Int

Foo undefined

Rational

Rational

Int

Integer

eqExpShell



ghc --make -O1 -prof -auto-all -o hlint

hlint src +RTS -p



unify



unify :: NameMatch -> Exp -> Exp -> Maybe [(String,Exp)]

unify nm (Do xs) (Do ys) | length xs == length ys = concatZipWithM (unifyStmt nm) xs ys

unify nm (Lambda _ xs x) (Lambda _ ys y) | length xs == length ys = liftM2 (++) (unify nm x y) (concatZipWithM unifyPat xs ys)

unify nm x y | isParen x || isParen y = unify nm (fromParen x) (fromParen y)

unify nm (Var (fromNamed -> v)) y | isUnifyVar v = Just [(v,y)]

unify nm (Var x) (Var y) | nm x y = Just []

unify nm x y | ((==) `on` descend (const $ toNamed "_")) x y = concatZipWithM (unify nm) (children x) (children y)

unify nm _ _ = Nothing



unify

unify

descend

(==)

descend

unify



eqExpShell :: Exp_ -> Exp_ -> Bool

eqExpShell = (==) `on` descend (const $ toNamed "_")



eqExpShell

toNamed "_"

toNamed

Do an []

an



eqExpShell :: Exp_ -> Exp_ -> Bool

eqExpShell = (==) `on` descend (const $ Do an [])



show

Show



eqExpShell :: Exp_ -> Exp_ -> Bool

eqExpShell x y =

((==) `on` constr) x y &&

((==) `on` descend (const $ Do an [])) x y

where constr = takeWhile (not . isSpace) . show



eqExpShell

constr

toConstr

Show

eqExpShell

eqExpShell

eqExpShell

Eq

geq



data Box = forall a . Data a => Box a



eqExpShellSYB :: Exp_ -> Exp_ -> Bool

eqExpShellSYB = f

where

f :: (Data a, Data b) => a -> b -> Bool

f x y = toConstr x == toConstr y &&

and (zipWith g (gmapQ Box x) (gmapQ Box y))



g (Box x) (Box y) = tx == typeAnn || tx == typeExp || f x y

where tx = typeOf x



typeAnn = typeOf an

typeExp = typeOf ex



toConstr

Eq

eqExpShell

eqExpShell

App

unify

App



unify nm (App _ x1 x2) (App _ y1 y2) = liftM2 (++) (unify nm x1 y1) (unify nm x2 y2)



App

eqExpShell

False



unify nm x y | isOther x && isOther y && eqExpShell x y = concatZipWithM (unify nm) (children x) (children y)

where

isOther Do{} = False

isOther Lambda{} = False

isOther Var{} = False

isOther App{} = False

isOther _ = True



eqExpShell

-caf-all

-caf-all

-O0

String



testN "Module" $ Module ssi Nothing [] [] []

testN "Decl" $ FunBind ssi []

testN "Exp" $ Do ssi []

testN "Pat" $ PWildCard ssi



testN :: Biplate a String => String -> a -> IO ()

testN msg x = do

t putStrLn $ "HSE for " ++ msg ++ " takes " ++ dp2 t ++ "s"



0.00



HSE for Module takes 0.54

HSE for Decl takes 0.86

HSE for Exp takes 2.54

HSE for Pat takes 0.32



Exp

String

Module



fixEq trans (populate box)



populate

trans

fixEq

Module

Exp

Exp



HSE for Module takes 0.03

HSE for Decl takes 0.00

HSE for Exp takes 0.00

HSE for Pat takes 0.00



matchIdea



matchIdea :: NameMatch -> Setting -> Exp_ -> Maybe Exp_

matchIdea nm MatchExp{lhs=lhs,rhs=rhs,side=side} x = do

u u guard $ checkSide side u

let rhs2 = subst u rhs

guard $ checkDot lhs rhs2

return $ unqualify nm $ dotContract $ performEval rhs2



lhs

x

fmap



parseString HSE.All 16.2 17.7

matchIdea Hint.Match 14.4 1.6

eqExpShellSlow HSE.Eq 9.2 11.4

listDecl Hint.List 6.1 4.1

lambdaHint Hint.Lambda 5.1 5.6

bracketHint Hint.Bracket 4.1 6.4

hasS Hint.Extensions 4.1 5.0

monadHint Hint.Monad 4.1 2.9

~= HSE.Match 4.1 2.5

isParen HSE.Util 3.1 0.0

