Skip to content

Commit e897d6a

Browse files
authored
Merge pull request #53 from haskellari/benchmark
Benchmark
2 parents 5f4c7a6 + 4a1254d commit e897d6a

File tree

6 files changed

+126
-8
lines changed

6 files changed

+126
-8
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
dist/
22
dist-newstyle/
33
.ghc.environment.*
4+
cabal.project.local
5+
6+
bench.html

bench/tree-diff-bench.hs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{-# OPTIONS -fno-warn-orphans #-}
2+
module Main (main) where
3+
4+
import Control.DeepSeq (NFData (..))
5+
import Control.Exception (evaluate)
6+
import Criterion.Main (bench, bgroup, defaultMain, nf)
7+
8+
import qualified Data.Algorithm.Diff as Diff
9+
10+
import Data.TreeDiff.List (diffBy)
11+
12+
smallA :: [Int]
13+
smallB :: [Int]
14+
15+
smallA = [0, 5 .. 100]
16+
smallB = [0, 3 .. 72]
17+
18+
bigA :: [Int]
19+
bigA = [0, 5 .. 10000]
20+
21+
bigB :: [Int]
22+
bigB = [0, 3 .. 7200]
23+
24+
main :: IO ()
25+
main = do
26+
evaluate (rnf smallA)
27+
evaluate (rnf smallB)
28+
29+
evaluate (rnf bigA)
30+
evaluate (rnf bigB)
31+
32+
defaultMain
33+
[ bgroup "same"
34+
[ bgroup "small"
35+
[ bench "lib" $ nf (uncurry (diffBy (==))) (smallA, smallA)
36+
, bench "Diff" $ nf (uncurry (Diff.getDiffBy (==))) (smallA, smallA)
37+
]
38+
, bgroup "big"
39+
[ bench "lib" $ nf (uncurry (diffBy (==))) (bigA, bigA)
40+
, bench "Diff" $ nf (uncurry (Diff.getDiffBy (==))) (bigA, bigA)
41+
]
42+
]
43+
, bgroup "different"
44+
[ bgroup "small"
45+
[ bench "lib" $ nf (uncurry (diffBy (==))) (smallA, smallB)
46+
, bench "Diff" $ nf (uncurry (Diff.getDiffBy (==))) (smallA, smallB)
47+
]
48+
, bgroup "big"
49+
[ bench "lib" $ nf (uncurry (diffBy (==))) (bigA, bigB)
50+
, bench "Diff" $ nf (uncurry (Diff.getDiffBy (==))) (bigA, bigB)
51+
]
52+
]
53+
]
54+
55+
-------------------------------------------------------------------------------
56+
-- Orphans
57+
-------------------------------------------------------------------------------
58+
59+
instance (NFData a, NFData b) => NFData (Diff.PolyDiff a b) where
60+
rnf (Diff.First x) = rnf x
61+
rnf (Diff.Second y) = rnf y
62+
rnf (Diff.Both x y) = rnf x `seq` rnf y

src/Data/TreeDiff/Expr.hs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ module Data.TreeDiff.Expr (
1212
import Prelude ()
1313
import Prelude.Compat
1414

15-
import Data.Semialign (alignWith)
16-
import Data.These (These (..))
15+
import Control.DeepSeq (NFData (..))
16+
import Data.Semialign (alignWith)
17+
import Data.These (These (..))
1718

1819
import Data.TreeDiff.List
1920
import Data.TreeDiff.OMap (OMap)
@@ -36,6 +37,11 @@ data Expr
3637
| Lst [Expr] -- ^ list constructor
3738
deriving (Eq, Show)
3839

40+
instance NFData Expr where
41+
rnf (App n es) = rnf n `seq` rnf es
42+
rnf (Rec n fs) = rnf n `seq` rnf fs
43+
rnf (Lst es) = rnf es
44+
3945
instance QC.Arbitrary Expr where
4046
arbitrary = QC.scale (min 25) $ QC.sized arb where
4147
arb n | n <= 0 = QC.oneof
@@ -109,3 +115,9 @@ data EditExpr
109115
| EditLst [Edit EditExpr]
110116
| EditExp Expr -- ^ unchanged tree
111117
deriving Show
118+
119+
instance NFData EditExpr where
120+
rnf (EditApp n es) = rnf n `seq` rnf es
121+
rnf (EditRec n fs) = rnf n `seq` rnf fs
122+
rnf (EditLst es) = rnf es
123+
rnf (EditExp e) = rnf e

src/Data/TreeDiff/List.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
-- | A list diff.
33
module Data.TreeDiff.List (diffBy, Edit (..)) where
44

5-
import Data.List.Compat (sortOn)
6-
import qualified Data.Vector as V
5+
import Control.DeepSeq (NFData (..))
6+
import Data.List.Compat (sortOn)
7+
8+
import qualified Data.Vector as V
79

810
-- | List edit operations
911
--
@@ -16,6 +18,12 @@ data Edit a
1618
| Swp a a -- ^ swap, i.e. delete + insert
1719
deriving Show
1820

21+
instance NFData a => NFData (Edit a) where
22+
rnf (Ins x) = rnf x
23+
rnf (Del x) = rnf x
24+
rnf (Cpy x) = rnf x
25+
rnf (Swp x y) = rnf x `seq` rnf y
26+
1927
-- | List difference.
2028
--
2129
-- >>> diffBy (==) "hello" "world"

src/Data/TreeDiff/OMap.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Data.List (sortBy)
1919
import Data.Ord (comparing)
2020
import Data.Semialign (Semialign (..))
2121
import Data.These (These (..))
22+
import Control.DeepSeq (NFData (..))
2223

2324
#if MIN_VERSION_containers(0,5,0)
2425
import qualified Data.Map.Strict as Map
@@ -67,6 +68,16 @@ instance (Eq k, Eq v) => Eq (OMap k v) where
6768
go ((k1, v1) : kvs1) ((k2, v2) : kvs2) =
6869
k1 == k2 && v1 == v2 && go kvs1 kvs2
6970

71+
-------------------------------------------------------------------------------
72+
-- deepseq
73+
-------------------------------------------------------------------------------
74+
75+
instance NFData v => NFData (Val v) where
76+
rnf (Val _ v) = rnf v
77+
78+
instance (NFData k, NFData v) => NFData (OMap k v) where
79+
rnf (OMap m) = rnf m
80+
7081
-------------------------------------------------------------------------------
7182
-- QuickCheck
7283
-------------------------------------------------------------------------------

tree-diff.cabal

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ library
8686
, base >=4.5 && <4.16
8787
, bytestring ^>=0.9.2.1 || ^>=0.10.0.2 || ^>=0.11.0.0
8888
, containers ^>=0.4.2.1 || ^>=0.5.0.0 || ^>=0.6.0.1
89+
, deepseq ^>=1.3.0.0 || ^>=1.4.0.0
8990
, parsec ^>=3.1.13.0
9091
, pretty ^>=1.1.1.0
9192
, text ^>=1.2.3.0
@@ -137,12 +138,14 @@ library
137138
hs-source-dirs: src
138139
default-language: Haskell2010
139140

140-
test-suite test
141+
test-suite tree-diff-test
141142
default-language: Haskell2010
142143
type: exitcode-stdio-1.0
143144
main-is: Tests.hs
144145
hs-source-dirs: tests
145146
ghc-options: -Wall -threaded
147+
148+
-- dependencies from library
146149
build-depends:
147150
, ansi-terminal
148151
, ansi-wl-pprint
@@ -151,11 +154,30 @@ test-suite test
151154
, parsec
152155
, QuickCheck
153156
, tagged
157+
, tree-diff
158+
159+
if impl(ghc <7.5)
160+
build-depends: ghc-prim
161+
162+
-- extra dependencies
163+
build-depends:
154164
, tasty ^>=1.2 || ^>=1.3.1
155165
, tasty-golden ^>=2.3.1.1
156166
, tasty-quickcheck ^>=0.10.1
157-
, tree-diff
158167
, trifecta >=2 && <2.2
159168

160-
if impl(ghc <7.5)
161-
build-depends: ghc-prim
169+
benchmark tree-diff-bench
170+
default-language: Haskell2010
171+
type: exitcode-stdio-1.0
172+
main-is: tree-diff-bench.hs
173+
hs-source-dirs: bench
174+
ghc-options: -Wall -threaded
175+
176+
-- dependencies from library
177+
build-depends:
178+
, base
179+
, deepseq
180+
, tree-diff
181+
182+
-- extra dependencies
183+
build-depends: criterion ^>=1.5.9.0, Diff ^>=0.4.0

0 commit comments

Comments
 (0)