summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2022-07-29 15:46:08 +0200
committerAndreas Klebinger <klebinger.andreas@gmx.at>2022-09-16 13:04:49 +0200
commitaebfa2dd4e41d0fd3dc89e33781f9b845cbaa522 (patch)
treeba2a9b88975ff096a4bcfc82774709a120527f5d
parentdf04d6ec6a543d8bf1b953cf27c26e63ec6aab25 (diff)
downloadhaskell-wip/andreask/perf-test-binary.tar.gz
Add a perf test for the generics code pattern from #21839.wip/andreask/perf-test-binary
This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future.
-rw-r--r--testsuite/tests/perf/compiler/T21839c.hs46
-rw-r--r--testsuite/tests/perf/compiler/T21839c.stdout1
-rw-r--r--testsuite/tests/perf/compiler/all.T7
-rw-r--r--testsuite/tests/perf/should_run/T21839r.hs46
-rw-r--r--testsuite/tests/perf/should_run/T21839r.stdout1
-rw-r--r--testsuite/tests/perf/should_run/all.T8
6 files changed, 109 insertions, 0 deletions
diff --git a/testsuite/tests/perf/compiler/T21839c.hs b/testsuite/tests/perf/compiler/T21839c.hs
new file mode 100644
index 0000000000..594459da03
--- /dev/null
+++ b/testsuite/tests/perf/compiler/T21839c.hs
@@ -0,0 +1,46 @@
+-- For in depth details see the ticket #21839. The short version:
+
+-- We noticed that GHC got slower compiling Cabal the libary.
+-- Eventually I narrowed it down to the pattern below of deriving Generics
+-- for a Enum, and then deriving a Binary instance for that Enum via Generics.
+-- A pattern very frequently used in Cabal.
+-- However this turned out to be a classic compile vs runtime tradeoff.
+-- In benchmarks I found the resulting code for the Binary instance was running
+-- more than twice as fast!
+-- So we decided to merely document this change and add a test representing this behaviour
+-- rather than trying to coax ghc back into its old behaviour.
+
+{-# LANGUAGE DeriveGeneric #-}
+
+{-# OPTIONS_GHC #-}
+module Main
+ ( main
+ ) where
+
+import GHC.Generics
+import Data.Typeable
+import Data.Binary
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.ByteString as BS
+
+data PathTemplateVariable =
+
+ Var0
+ | Var1
+ | Var2
+ | Var3
+ | Var4
+ | Var5
+ | Var6
+ | Var7
+ | Var8
+ | Var9
+ deriving (Generic,Enum)
+
+instance Binary PathTemplateVariable
+
+main :: IO ()
+main = do
+ let lists = replicate 10000 Var0
+ lbs = encode lists
+ print $ BS.length $ BS.toStrict lbs
diff --git a/testsuite/tests/perf/compiler/T21839c.stdout b/testsuite/tests/perf/compiler/T21839c.stdout
new file mode 100644
index 0000000000..b95ab72342
--- /dev/null
+++ b/testsuite/tests/perf/compiler/T21839c.stdout
@@ -0,0 +1 @@
+10008
diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T
index cac2ebd48f..a70b93df01 100644
--- a/testsuite/tests/perf/compiler/all.T
+++ b/testsuite/tests/perf/compiler/all.T
@@ -643,3 +643,10 @@ test ('T20261',
[collect_compiler_stats('all')],
compile,
[''])
+
+# Track perf of generics based binary instances
+test('T21839c',
+ [ collect_compiler_stats('all', 1),
+ only_ways(['normal'])],
+ compile,
+ ['-O']) \ No newline at end of file
diff --git a/testsuite/tests/perf/should_run/T21839r.hs b/testsuite/tests/perf/should_run/T21839r.hs
new file mode 100644
index 0000000000..594459da03
--- /dev/null
+++ b/testsuite/tests/perf/should_run/T21839r.hs
@@ -0,0 +1,46 @@
+-- For in depth details see the ticket #21839. The short version:
+
+-- We noticed that GHC got slower compiling Cabal the libary.
+-- Eventually I narrowed it down to the pattern below of deriving Generics
+-- for a Enum, and then deriving a Binary instance for that Enum via Generics.
+-- A pattern very frequently used in Cabal.
+-- However this turned out to be a classic compile vs runtime tradeoff.
+-- In benchmarks I found the resulting code for the Binary instance was running
+-- more than twice as fast!
+-- So we decided to merely document this change and add a test representing this behaviour
+-- rather than trying to coax ghc back into its old behaviour.
+
+{-# LANGUAGE DeriveGeneric #-}
+
+{-# OPTIONS_GHC #-}
+module Main
+ ( main
+ ) where
+
+import GHC.Generics
+import Data.Typeable
+import Data.Binary
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.ByteString as BS
+
+data PathTemplateVariable =
+
+ Var0
+ | Var1
+ | Var2
+ | Var3
+ | Var4
+ | Var5
+ | Var6
+ | Var7
+ | Var8
+ | Var9
+ deriving (Generic,Enum)
+
+instance Binary PathTemplateVariable
+
+main :: IO ()
+main = do
+ let lists = replicate 10000 Var0
+ lbs = encode lists
+ print $ BS.length $ BS.toStrict lbs
diff --git a/testsuite/tests/perf/should_run/T21839r.stdout b/testsuite/tests/perf/should_run/T21839r.stdout
new file mode 100644
index 0000000000..b95ab72342
--- /dev/null
+++ b/testsuite/tests/perf/should_run/T21839r.stdout
@@ -0,0 +1 @@
+10008
diff --git a/testsuite/tests/perf/should_run/all.T b/testsuite/tests/perf/should_run/all.T
index eb5124a155..9059a6f92f 100644
--- a/testsuite/tests/perf/should_run/all.T
+++ b/testsuite/tests/perf/should_run/all.T
@@ -395,3 +395,11 @@ test('T19347',
compile_and_run,
['-O'])
+# Track perf of generics based binary instances
+test('T21839r',
+ [ collect_stats('bytes allocated', 10),
+ collect_runtime_residency(10),
+ collect_compiler_stats('bytes allocated', 1),
+ only_ways(['normal'])],
+ compile_and_run,
+ ['-O'])