Skip to content

Worse performance with -O

The running time of the following program worsens when compiled with -O, and worsens more when compiled with ghc-7.10.2.

-- /opt/ghc-7.8.3/bin/ghc --make -threaded -fforce-recomp test.hs
-- time ./test: 3 seconds
--
-- /opt/ghc-7.8.3/bin/ghc --make -threaded -O -fforce-recomp test.hs
-- time ./test: 11 seconds
--
-- /opt/ghc-7.10.2/bin/ghc --make -threaded -fforce-recomp test.hs
-- time ./test: 5 seconds
--
-- /opt/ghc-7.10.2/bin/ghc --make -threaded -O -fforce-recomp test.hs
-- time ./test: 13 seconds
--

import Control.Concurrent
import Control.Monad
import Data.List

main :: IO ()
main = do
  let x = foldl' (+) 0 [1 .. 100000000]
  mv <- newEmptyMVar
  replicateM_ 4 $ forkIO $ putMVar mv $! x
  nums <- replicateM 4 $ takeMVar mv
  print (nums :: [Integer])

The following variant which doesn't share x improves with -O for ghc-7.10.2, but ghc-7.8.3 still produces a faster program.

-- /opt/ghc-7.8.3/bin/ghc --make -threaded -fforce-recomp test.hs
-- time ./test: 10 seconds
--
-- /opt/ghc-7.8.3/bin/ghc --make -threaded -O -fforce-recomp test.hs
-- time ./test: 11 seconds
--
-- /opt/ghc-7.10.2/bin/ghc --make -threaded -fforce-recomp test.hs
-- time ./test: 18 seconds
--
-- /opt/ghc-7.10.2/bin/ghc --make -threaded -O -fforce-recomp test.hs
-- time ./test: 15 seconds
--

import Control.Concurrent
import Control.Monad
import Data.IORef
import Data.List

main :: IO ()
main = do
  mv <- newEmptyMVar
  ref <- newIORef 0
  replicateM_ 4 $ forkIO $ do
    i <- readIORef ref
    putMVar mv $! foldl' (+) i [1 .. 100000000]
  nums <- replicateM 4 $ takeMVar mv
  print (nums :: [Integer])

Some related discussion here.

Trac metadata
Trac field Value
Version
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information