`checkPackageProblems` is very slow on large packages
- Dominant language
- Haskell
- Stars
- 1.7k
- Forks
- 750
- Avg merge
- 4d 3h
- Merged PRs (30d)
- 28
Description
Our `.cabal` file is now about 26k lines long. This results in a `configure` step taking around 40 seconds. I did some analysis and `checkPackage` ends up taking 30 seconds. This was validated in our codebase with the following patch:
```
diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs
index 8d3f91e84..d9d04186e 100644
--- a/Cabal/src/Distribution/Simple/Configure.hs
+++ b/Cabal/src/Distribution/Simple/Configure.hs
@@ -2779,11 +2779,18 @@ checkPackageProblems
-> GenericPackageDescription
-> PackageDescription
-> IO ()
-checkPackageProblems verbosity dir gpkg pkg = do
+checkPackageProblems verbosity dir _gpkg pkg = do
ioChecks <- checkPackageFiles verbosity pkg dir
- let pureChecks = checkPackage gpkg
- (errors, warnings) =
- partitionEithers (M.mapMaybe classEW $ pureChecks ++ ioChecks)
+ -- Note: We intentionally skip 'checkPackage' (pure GPD checks) here.
+ -- These checks are very expensive for large packages — they perform O(n)
+ -- traversals across all modules for each check, which can take 30+ seconds
+ -- for packages with ~20k modules. During configure, we only use
+ -- PackageBuildImpossible and PackageBuildWarning results anyway, and the
+ -- build-impossible conditions (duplicate modules, missing autogen modules)
+ -- will be caught as compilation errors. Distribution-quality checks are
+ -- still available via 'cabal check'.
+ let (errors, warnings) =
+ partitionEithers (M.mapMaybe classEW ioChecks)
if null errors
then traverse_ (warn verbosity . ppPackageCheck) warnings
else dieWithException verbosity $ CheckPackageProblems (map ppPackageCheck errors)
```
I'm investigating ways to speed this up for now, but wanted to surface this as a performance issue for us.
Contributor guide
Assessment
This issue has not been assessed yet.