Performance regression in for_ alternatives from GHC 8.2.2 to newer GHCs
We are investigating various ways to make for_ and traverse_ not leak space by changing the type signature from (a -> f b) -> t a -> f () to (a -> f ()) -> t a -> f ().
While doing so, we noticed a regression from GHC 8.2.2 to 8.4.3 and 8.6.1.
The code:
Run against 3 different GHC releases:
# 8.2.2
stack --resolver lts-11.22 ghc -- --make -O2 -rtsopts ./TraverseMaybePerformance.hs && /usr/bin/time ./TraverseMaybePerformance 8 +RTS -sstderr
460,309,368 bytes allocated in the heap
# 8.4.3
stack --resolver lts-12.11 ghc -- --make -O2 -rtsopts ./TraverseMaybePerformance.hs && /usr/bin/time ./TraverseMaybePerformance 8 +RTS -sstderr
860,301,736 bytes allocated in the heap
# 8.6.1
stack --resolver nightly-2018-10-06 ghc -- --make -O2 -rtsopts ./TraverseMaybePerformance.hs && /usr/bin/time ./TraverseMaybePerformance 8 +RTS -sstderr
860,301,784 bytes allocated in the heap
Allocations doubled starting with 8.4.
All was run on Ubuntu 16.04 64-bit.
We haven't investigated in detail yet (also whether it's a GHC or libraries problem) since we're actually trying to do something else and this came out on the side, but it looks important enough to share already.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | nh2 |
| Operating system | |
| Architecture |