Skip to content

Performance regression in ormolu HEAD #897

@parsonsmatt

Description

@parsonsmatt

Describe the bug

We were running fourmolu-0.3.0.0 to format all of our code at work, and it would take about a minute for 3,000+ source files and 250kloc. I upgraded to fourmolu-0.7.0.0 which is based on ormolu-0.5.0.0 and this resulted in a massive slowdown: the same task now takes 20-30 minutes to run. I've tested ormolu-0.5.0.0 (installed from Hackage, as well as HEAD on master here) and the performance problem remains.

As described in #896 , you can get nice multithreading which ameliorates the problem using fd (thanks @amesgen!). On my machine, this decreased the time to about 5 minutes. This is acceptable, but not ideal.

I got HEAD building with this diff to stack.yaml:

diff --git a/stack.yaml b/stack.yaml
index cf17657..64026cf 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,4 +1,4 @@
-resolver: lts-19.2
+resolver: lts-19.11
 
 packages:
 - '.'
@@ -7,7 +7,7 @@ packages:
 
 extra-deps:
 - Cabal-3.6.2.0
-- ghc-lib-parser-9.2.1.20211101
+  # - ghc-lib-parser-9.2.1.20211101
 
 nix:
   packages:

Building with this command:

stack install . --executable-profiling --resolver nightly --library-profiling --profile

And finally running on three large test files (about 9kloc between them):

ormolu --mode check src/Client/Apex/Types/Atlas.hs test/Gen.hs src/Client/Bank/Primitive.hs +RTS -p -RTS

The top few lines of the profile give everywhere and thenP as our pproblems, taking up 38% of runtime.

	Tue Jun 14 10:15 2022 Time and Allocation Profiling Report  (Final)

	   ormolu +RTS -p -RTS --mode check src/Client/Apex/Types/Atlas.hs test/Gen.hs src/Client/Bank/Primitive.hs

	total time  =        8.49 secs   (8487 ticks @ 1000 us, 1 processor)
	total alloc = 5,711,086,104 bytes  (excludes profiling overheads)

COST CENTRE                                 MODULE                              SRC                                                                   %time %alloc

everything.go                               Data.Generics.Schemes               src/Data/Generics/Schemes.hs:122:5-37                                  22.1    4.1
thenP.\                                     GHC.Parser.Lexer                    compiler/GHC/Parser/Lexer.x:(2396,9)-(2398,40)                         16.4    1.8
==                                          Distribution.Utils.ShortText        src/Distribution/Utils/ShortText.hs:96:29-30                            4.2    0.0
matchIgnoringSrcSpans.genericQuery          Ormolu.Diff.ParseResult             src/Ormolu/Diff/ParseResult.hs:(77,5)-(104,32)                          3.9    0.0
<>.combineNub                               Distribution.Types.BuildInfo        src/Distribution/Types/BuildInfo.hs:215:7-44                            3.7    0.1
getExtensionAndDepsMap.buildMap             Ormolu.Utils.Cabal                  src/Ormolu/Utils/Cabal.hs:(164,5)-(167,40)                              2.1    0.4
ext1                                        Data.Generics.Aliases               src/Data/Generics/Aliases.hs:326:1-43                                   1.5    1.4
linesInRegion                               Ormolu.Processing.Common            src/Ormolu/Processing/Common.hs:(38,1)-(41,67)                          1.3    4.6
gfoldlAccum                                 Data.Generics.Twins                 src/Data/Generics/Twins.hs:(91,1)-(94,26)                               1.2    0.1

I've generated a flamegraph from this profile:

02-head

This points to a potential regression in the Data.Generics.Schemes code. I'm curious if we have a regression that is related to Simplified Subsumption, since that module makes heavy use of the GenericQ type alias, which is type GenericQ r = forall a. Data a => a -> r.

everything is defined here, and it is used in ormolu through the listify function.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions