Skip to content

Commit f158128

Browse files
soulomoonfendor
andauthored
Fix benchmark (#4928)
Three things have been done. 1. enhence the checking before benchmark, ensure the target repo actually buildable and the targets file actually exist. 2. we no longer generating the visualisations for the memory usage. 3. bump ghc and cabal version and update the target repos. Instead of leaving the benchmark stale, we leave just enough functionalities for our CI. --------- Co-authored-by: fendor <fendor@users.noreply.github.com>
1 parent 56a15df commit f158128

9 files changed

Lines changed: 130 additions & 353 deletions

File tree

.github/workflows/bench.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,20 @@ jobs:
1919
runs-on: ubuntu-latest
2020
outputs:
2121
should_skip: ${{ steps.skip_check.outputs.should_skip }}
22+
bench_ghc_versions: ${{ steps.set_ghc_versions.outputs.versions }}
2223
steps:
24+
- id: set_ghc_versions
25+
run: |
26+
# benching the two latest GHCs we support now
27+
# since benchmark are expansive.
28+
# choosing the two latest are easier to maintain and more forward looking
29+
# see discussion https://github.com/haskell/haskell-language-server/pull/4118
30+
# Benchmarking only the two latest GHCs we support now
31+
# since benchmark are expensive.
32+
# Choosing the two latest is easier to maintain and more forward looking.
33+
# See discussion https://github.com/haskell/haskell-language-server/pull/4118
34+
# also possible to add more GHCs if we perform better in the future.
35+
echo 'versions=["9.12", "9.14"]' >> $GITHUB_OUTPUT
2336
- id: skip_check
2437
uses: fkirc/skip-duplicate-actions@v5.3.1
2538
with:
@@ -45,14 +58,7 @@ jobs:
4558
strategy:
4659
fail-fast: false
4760
matrix:
48-
# benching the two latest GHCs we support now
49-
# since benchmark are expansive.
50-
# choosing the two latest are easier to maintain and more forward looking
51-
# see discussion https://github.com/haskell/haskell-language-server/pull/4118
52-
# also possible to add more GHCs if we performs better in the future.
53-
ghc:
54-
- '9.8'
55-
- '9.10'
61+
ghc: ${{ fromJSON(needs.pre_job.outputs.bench_ghc_versions) }}
5662
os:
5763
- ubuntu-latest
5864

@@ -120,9 +126,9 @@ jobs:
120126
strategy:
121127
fail-fast: false
122128
matrix:
123-
ghc: ['9.8', '9.10']
129+
ghc: ${{ fromJSON(needs.pre_job.outputs.bench_ghc_versions) }}
124130
os: [ubuntu-latest]
125-
cabal: ['3.14']
131+
cabal: ['3.16']
126132
example: ['cabal', 'lsp-types']
127133

128134
steps:
@@ -161,7 +167,7 @@ jobs:
161167
column -s, -t < bench-results/unprofiled/${{ matrix.example }}/resultDiff.csv | tee bench-results/unprofiled/${{ matrix.example }}/resultDiff.txt
162168
163169
- name: tar benchmarking artifacts
164-
run: find bench-results -name "*.csv" -or -name "*.svg" -or -name "*.html" | xargs tar -czf benchmark-artifacts.tar.gz
170+
run: find bench-results -name "*.csv" | xargs tar -czf benchmark-artifacts.tar.gz
165171

166172
- name: Archive benchmarking artifacts
167173
uses: actions/upload-artifact@v6

bench/Main.hs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@
2020
| └── <HLS plugin>
2121
│   ├── <experiment>.gcStats.log - RTS -s output
2222
│   ├── <experiment>.csv - stats for the experiment
23-
│   ├── <experiment>.svg - Graph of bytes over elapsed time
24-
│   ├── <experiment>.diff.svg - idem, including the previous version
2523
│   ├── <experiment>.log - ghcide-bench output
2624
│   └── results.csv - results of all the experiments for the example
2725
├── results.csv - aggregated results of all the experiments and versions
28-
└── <experiment>.svg - graph of bytes over elapsed time, for all the included versions
26+
└── resultDiff.csv - diff of aggregated results compared with previous version
2927
30-
For diff graphs, the "previous version" is the preceding entry in the list of versions
28+
For diff results, the "previous version" is the preceding entry in the list of versions
3129
in the config file. A possible improvement is to obtain this info via `git rev-list`.
3230
3331
To execute the script:
@@ -36,8 +34,8 @@
3634
3735
To build a specific analysis, enumerate the desired file artifacts
3836
39-
> stack bench --ba "bench-results/HEAD/results.csv bench-results/HEAD/edit.diff.svg"
40-
> cabal bench --benchmark-options "bench-results/HEAD/results.csv bench-results/HEAD/edit.diff.svg"
37+
> stack bench --ba "bench-results/HEAD/results.csv"
38+
> cabal bench --benchmark-options "bench-results/HEAD/results.csv"
4139
4240
-}
4341
{-# LANGUAGE DeriveAnyClass #-}
@@ -165,8 +163,6 @@ createBuildSystem config = do
165163
benchRules build (MkBenchRules (askOracle $ GetSamples ()) benchHls warmupHls "haskell-language-server" (parallelism configStatic))
166164
addGetParentOracle
167165
csvRules build
168-
svgRules build
169-
heapProfileRules build
170166
phonyRules "" binaryName NoProfiling build (examples configStatic)
171167

172168
whenJust (profileInterval configStatic) $ \i -> do

bench/README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,30 @@ The Shake script supports a number of phony targets that allow running a subset
4141
```
4242
Targets:
4343
- bench-results/binaries/*/commitid
44-
- bench-results/binaries/HEAD/ghcide
44+
- bench-results/binaries/HEAD/haskell-language-server
4545
- bench-results/binaries/HEAD/ghc.path
46-
- bench-results/binaries/*/ghcide
46+
- bench-results/binaries/*/haskell-language-server
4747
- bench-results/binaries/*/ghc.path
4848
- bench-results/binaries/*/*.warmup
49-
- bench-results/*/*/*/*.csv
50-
- bench-results/*/*/*/*.gcStats.log
51-
- bench-results/*/*/*/*.output.log
52-
- bench-results/*/*/*/*.eventlog
53-
- bench-results/*/*/*/*.hp
49+
- bench-results/*/*/*/*/*.csv
50+
- bench-results/*/*/*/*/*.gcStats.log
51+
- bench-results/*/*/*/*/*.output.log
52+
- bench-results/*/*/*/*/*.eventlog
53+
- bench-results/*/*/*/*/*.hp
54+
- bench-results/*/*/*/*/results.csv
55+
- bench-results/*/*/*/*/resultDiff.csv
5456
- bench-results/*/*/*/results.csv
55-
- bench-results/*/*/results.csv
56-
- bench-results/*/results.csv
5757
- bench-results/*/*/*/resultDiff.csv
58+
- bench-results/*/*/results.csv
5859
- bench-results/*/*/resultDiff.csv
60+
- bench-results/*/results.csv
5961
- bench-results/*/resultDiff.csv
60-
- bench-results/*/*/*/*.svg
61-
- bench-results/*/*/*/*.diff.svg
62-
- bench-results/*/*/*.svg
63-
- bench-results/*/*/*/*.heap.svg
64-
- Cabal-3.0.0.0
65-
- lsp-types-1.0.0.1
62+
- cabal
63+
- lsp-types
6664
- all
67-
- profiled-Cabal-3.0.0.0
68-
- profiled-lsp-types-1.0.0.1
65+
- all-binaries
66+
- profiled-cabal
67+
- profiled-lsp-types
6968
- profiled-all
69+
- profiled-all-binaries
7070
```

bench/config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ examples:
2121
# Medium-sized project without TH
2222
- name: cabal
2323
package: Cabal
24-
version: 3.10.2.1
24+
version: 3.16.1.0
2525
modules:
2626
- src/Distribution/Simple.hs
2727
- src/Distribution/Types/ComponentLocalBuildInfo.hs
2828
extra-args: [] # extra HLS command line args
2929
# Small-sized project with TH
3030
- name: lsp-types
3131
package: lsp-types
32-
version: 2.1.1.0
32+
version: 2.4.0.0
3333
modules:
3434
- src/Language/LSP/Protocol/Types/SemanticTokens.hs
3535
- generated/Language/LSP/Protocol/Internal/Types/NotebookDocumentChangeEvent.hs

cabal.project

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ constraints:
5151
allow-newer:
5252
cabal-install-parsers:Cabal-syntax,
5353

54-
if impl(ghc >= 9.11)
55-
benchmarks: False
54+
55+
if impl(ghc >= 9.13)
5656
allow-newer:
5757
cabal-install-parsers:base,
5858
cabal-install-parsers:time,

ghcide-bench/src/Experiments.hs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,21 +708,20 @@ setup = do
708708
package = packageName <> "-" <> showVersion packageVersion
709709
hieYamlPath = path </> "hie.yaml"
710710
alreadySetup <- doesDirectoryExist path
711-
unless alreadySetup $
712-
case buildTool ?config of
711+
case buildTool ?config of
713712
Cabal -> do
714713
let cabalVerbosity = "-v" ++ show (fromEnum (verbose ?config))
715-
callCommandLogging $ "cabal get " <> cabalVerbosity <> " " <> package <> " -d " <> examplesPath
716-
let hieYamlPath = path </> "hie.yaml"
714+
unless alreadySetup $
715+
callCommandLogging $ "cabal get " <> cabalVerbosity <> " " <> package <> " -d " <> examplesPath
717716
writeFile hieYamlPath simpleCabalCradleContent
718717
-- Need this in case there is a parent cabal.project somewhere
719718
writeFile
720719
(path </> "cabal.project")
721-
"packages: ."
720+
(cabalProjectForPackage ExamplePackage{..})
722721
writeFile
723722
(path </> "cabal.project.local")
724723
""
725-
Stack -> do
724+
Stack -> unless alreadySetup $ do
726725
let stackVerbosity = case verbosity ?config of
727726
Quiet -> "--silent"
728727
Normal -> ""
@@ -745,6 +744,11 @@ setup = do
745744
writeFile hieYamlPath simpleStackCradleContent
746745
return path
747746

747+
checkExampleModulesExist benchDir (example ?config)
748+
case (buildTool ?config, exampleDetails (example ?config)) of
749+
(Cabal, ExampleHackage{}) -> buildCabalExample benchDir
750+
_ -> return ()
751+
748752
whenJust (shakeProfiling ?config) $ createDirectoryIfMissing True
749753

750754
let cleanUp = case exampleDetails (example ?config) of
@@ -756,6 +760,30 @@ setup = do
756760

757761
return SetupResult{..}
758762

763+
checkExampleModulesExist :: FilePath -> Example -> IO ()
764+
checkExampleModulesExist benchDir Example{..} =
765+
forM_ exampleModules $ \target -> do
766+
let fullPath = benchDir </> target
767+
exists <- doesFileExist fullPath
768+
unless exists $
769+
fail $ "Benchmark example " <> show exampleName
770+
<> " is missing target file " <> show target
771+
<> " at " <> fullPath
772+
773+
buildCabalExample :: HasConfig => FilePath -> IO ()
774+
buildCabalExample path = do
775+
output $ "cabal build all -j in " <> path
776+
cmd_ (Cwd path) ("cabal" :: String) (["build", "all", "-j"] :: [String])
777+
778+
cabalProjectForPackage :: ExamplePackage -> String
779+
cabalProjectForPackage ExamplePackage{packageName = "lsp-types"} =
780+
unlines
781+
[ "packages: ."
782+
, "allow-newer: boring:base"
783+
]
784+
cabalProjectForPackage _ =
785+
"packages: ."
786+
759787
setupDocumentContents :: Config -> Session [DocumentPositions]
760788
setupDocumentContents config =
761789
forM (exampleModules $ example config) $ \m -> do

haskell-language-server.cabal

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,8 +1979,7 @@ benchmark benchmark
19791979
main-is: Main.hs
19801980
hs-source-dirs: bench
19811981
build-tool-depends:
1982-
haskell-language-server:ghcide-bench,
1983-
eventlog2html:eventlog2html,
1982+
haskell-language-server:ghcide-bench
19841983
default-extensions:
19851984
LambdaCase
19861985
RecordWildCards

shake-bench/shake-bench.cabal

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,12 @@ source-repository head
1616
location: https://github.com/haskell/haskell-language-server.git
1717

1818
library
19-
if impl(ghc > 9.11)
20-
buildable: False
2119
exposed-modules: Development.Benchmark.Rules
2220
hs-source-dirs: src
2321
build-depends:
2422
aeson,
2523
base == 4.*,
2624
bytestring,
27-
Chart,
28-
Chart-diagrams,
29-
diagrams-contrib,
30-
diagrams-core,
31-
diagrams-lib,
32-
diagrams-svg,
3325
directory,
3426
extra >= 1.7.2,
3527
filepath,

0 commit comments

Comments
 (0)