Project Euler 14: performance compared to C and memoization

后端 未结 3 570
情歌与酒
情歌与酒 2021-01-11 14:34

I\'m currently working on project euler problem 14.

I solved it using a poorly coded program, without memoization, that took 386 5 seconds to run (s

3条回答
  •  孤城傲影
    2021-01-11 14:47

    On my current system (32-bit Core2Duo) your Haskell code, including all the optimizations given in the answers, takes 0.8s to compile and 1.2s to run.

    You could transfer the run-time to compile-time, and reduce the run-time to nearly zero.

    module Euler14 where
    
    import Data.Word
    import Language.Haskell.TH
    
    terms :: Word -> Word
    terms n = countTerms n 0
      where
        countTerms 1 acc             = acc + 1
        countTerms n acc | even n    = countTerms (n `div` 2) (acc + 1)
                         | otherwise = countTerms (3 * n + 1) (acc + 1)
    
    longestT :: Word -> Word -> (Word, Word) 
    longestT mi mx = find mi mx (0, 0)
      where
          find mi mx (ct,cn) | mi == mx  = if ct > terms mi then (ct,cn) else (terms mi, mi)
                             | otherwise = find (mi + 1) mx
                                           (if ct > terms mi then (ct,cn) else (terms mi, mi))
    
    longest :: Word -> Word -> ExpQ
    longest mi mx = return $ TupE [LitE (IntegerL (fromIntegral a)),
                                   LitE (IntegerL (fromIntegral b))]
      where
        (a,b) = longestT mi mx
    

    and

    {-# LANGUAGE TemplateHaskell #-}
    import Euler14
    
    main = print $(longest 500000 999999)
    

    On my system it takes 2.3s to compile this but the run-time goes down to 0.003s. Compile Time Function Execution (CTFE) is something you can't do in C/C++. The only other programming language that I know of that supports CTFE is the D programming language. And just to be complete, the C code takes 0.1s to compile and 0.7s to run.

提交回复
热议问题