Skip to content

Massive performance issue between interpreted and compiled code. (Interpreted is faster!)

I was unable to reduce this to a minimal example, but it's not hard to recreate. I've observed this all the way back to GHC 8.8, and perhaps earlier. Both Mac and Linux. (However, I think this is a regression, i.e., older GHCs--from back about 3 years ago--didn't have this issue. Though I don't have any specific info on versions where it was not an issue.)

The numbers reported below are with GHC 9.8.1.

To replicate, you'll need to have SBV installed. (https://hackage.haskell.org/package/sbv)

For this program:

import Data.SBV
import Data.SBV.Tools.CodeGen
import Documentation.SBV.Examples.Crypto.SHA

main :: IO ()
main = compileToC (Just "testOutput_delete") "sha512" $ do

        cgOverwriteFiles True

        let algorithm = sha512P

        hInBytes   <- cgInputArr  64 "hIn"
        blockBytes <- cgInputArr 128 "block"

        let hIn   = chunkBy 8 fromBytes hInBytes
            block = chunkBy 8 fromBytes blockBytes

            result = hashBlock algorithm hIn (Block block)

        cgOutputArr "hash" $ concatMap toBytes result

I'm seeing:

$ time ghc -e main a
ghc -e main a  62.22s user 9.47s system 85% cpu 1:24.18 total

That's kind of slow, but not too bad. But when I compile:

$ ghc a.hs
Loaded package environment from /Users/leventerkok/.ghc/x86_64-darwin-9.8.1/environments/default
[1 of 2] Compiling Main             ( a.hs, a.o )
[2 of 2] Linking a
time ./ald: warning: ignoring duplicate libraries: '-lm'
$ time ./a
./a  820.27s user 15.34s system 99% cpu 14:04.02 total

That is significantly slower; in fact 10 times slower than the interpreted code. Compiling with optimizations (-O2) doesn't change the run-time.

I'd appreciate any insights into what might be going wrong.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information