Skip to content

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:

https://gist.github.com/nh2/b8f9f8e60443bdb30c1cd7e0acb8c8eb/bb1cc1a4987091fcd41c07b0a6f0512f96a992ae

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information