Performance Tests in Haskell

Hi all, i have changed the compilation flags and the codes as you said. It seems to me that it worked, since the runtime of my test stabilized at 2002ns. Before, i got sometimes 4004ns. The bigger runtime part is now (as far as i can guess, see below why) the screen output. That brings me to two issues for performance tests in Haskell: 1. how can i do performance tests if the tests are small? In imperative languages, you cycle through 1000 times and divide the runtime by 1000. How can i do something similar in haskell? 2. How do i get haskell to do something _without_ printing anything on the screen? For now, i do something like main = do startt <- getCPUTime putStr $ (show testAIBD1) ++ ", " ++ (show testZins1) endt <- getCPUTime putStr $ "\tTook " ++ (show $ (endt - startt) `div` ((10^6) * 5)) ++ " ns\n" where testAIBD1 is a sum of 40 calculation results and also is testZins1. Another issue: with foreign C calls i have the problem to link automatically. i type something like
ghc --make Main.hs -fglasgow-exts -O2 -fliberate-case-threshold100 -funbox-strict-fields -fvia-C while having compiled the external C HAIBDUtil.c with HAIBDUtil.h to HAIBDUtil.o. As result, i get
Chasing modules from: Main.hs Compiling AIBD ( AIBD.hs, ./AIBD.o ) Compiling Main ( Main.hs, ./Main.o ) Linking ... AIBD.o(.text+0x11e0):ghc1052.hc: undefined reference to `caibd' shure, "caibd" is the called C procedure from AIBD. well then, i type
ghc Main.o AIBD.o HAIBDUtil.o -o HAIBD.exe
then everything is fine, and i get my executable. Now i wanted to profile, and added the options "-prof --auto-all" to the first ghc command. When trying to link, i get lot's of undefined references:
ghc Main.o AIBD.o HAIBDUtil.o -o HAIBD.exe
AIBD.o(.text+0x425):ghc1364.hc: undefined reference to `CC_LIST' AIBD.o(.text+0x430):ghc1364.hc: undefined reference to `CC_LIST' AIBD.o(.text+0x439):ghc1364.hc: undefined reference to `CC_ID' AIBD.o(.text+0x444):ghc1364.hc: undefined reference to `CC_ID' (...) AIBD.o(.text+0x5fc):ghc1364.hc: undefined reference to `CCCS' AIBD.o(.text+0x605):ghc1364.hc: undefined reference to `CCCS' AIBD.o(.text+0x626):ghc1364.hc: undefined reference to `PushCostCentre' (...) Obviously (see "PushCostCentre" as last misssing reference), something for profiling is missing. What is it? Regards, Andreas Schroeder |---------+-----------------------------------------> | | Andreas.Schroeder@gillardon.de| | | Gesendet von: | | | glasgow-haskell-users-bounces@| | | haskell.org | | | | | | | | | 16.10.2003 09:37 | | | | |---------+----------------------------------------->
-------------------------------------------------------------------------------------------------------------------| | | | An: glasgow-haskell-users@haskell.org | | Kopie: chak@cse.unsw.edu.au | | Thema: Re: GHC with MS .Net 2003 C compiler | -------------------------------------------------------------------------------------------------------------------|
Hi all, hi Manuel,
thanks for the help. Yes, i read the user docs for "earlier, faster,
thriftier, smaller ..." or a permutation of this,
but i do not _really_ remember from my university time what strict
functions are. Is by strict meant as in Formal OO that
a function is trict iff its result is _|_ iff any of its arguments is _|_ ?
I will try to use
data Genauigkeit = Absolut {wert, intervall :: !Double}
| Intervall !Double
is that what you meant? I will read the strictness flag documentation.
Thanks for the hints.
Regards,
Andreas Schroeder
|---------+----------------------------------------->
| | Manuel M T Chakravarty |
| |
-------------------------------------------------------------------------------------------------------------------| | | | An: Andreas.Schroeder@gillardon.de | | Kopie: glasgow-haskell-users@haskell.org | | Thema: Re: GHC with MS .Net 2003 C compiler |
-------------------------------------------------------------------------------------------------------------------| Andreas.Schroeder@gillardon.de wrote, Generally, did you look at http://haskell.org/ghc/docs/latest/html/users_guide/faster.html
module AIBD(aibd, rechneZins, rechneRate, rechneKapital) where import Foreign(unsafePerformIO)
type Funktion = Double -> Double
data Genauigkeit = Absolut {wert, intervall :: Double} | Intervall Double
See the paragraph under "Use strictness annotations" on the above web page on how to use strictness annotations to speed this data type up.
istOk :: Genauigkeit -> Double -> Double -> Bool istOk (Absolut w i) x _ = abs (x-w) <= i istOk (Intervall i) _ dx = abs dx <= i
sekantenVerfahren :: Funktion -> Genauigkeit -> Genauigkeit -> Int -> Double -> Double sekantenVerfahren f gx gy tiefe start = sekantenIter f tiefe gx gy x1 x2 y1 y2 where x1 = start x2 = start + start * 0.1 y1 = f x1 y2 = f x2 sekantenIter _ 0 _ _ _ x2 _ _ = x2 sekantenIter f tiefe gx gy x1 x2 y1 y2 = let x3 = x2 - y2 * (x2 - x1) / (y2 - y1) y3 = f x3 dy = y3 - y2 dx = x3 - x2 in if (istOk gx x3 dx) && (istOk gy y3 dy) then x3 else sekantenIter f (tiefe-1) gx gy x2 x3 y2 y3
Code like this may benefit from using the option "-O2" and possibly also "-fliberate-case-threshold100" http://haskell.org/ghc/docs/latest/html/users_guide/flag-reference.html#AEN5...
foreign import ccall "HAIBDUtil.h caibd" caibd :: Double -> Double -> Double -> Int -> IO Double
aibd:: Double -> Double -> Double -> Int -> Double aibd kapital zins rate jahre = unsafePerformIO (caibd kapital zins rate jahre) {- does the same than aibd:: Double -> Double -> Double -> Int -> Double aibd kapital _ _ 0 = kapital aibd kapital zins rate jahre = aibd (kapital + kapital * zins - rate) zins rate (jahre-1) -}
Two comments with -O2 -fliberate-case-threshold100 the Haskell version may be as fast as the C version. If not, better foreign import as a pure functions foreign import ccall "HAIBDUtil.h caibd" caibd :: Double -> Double -> Double -> Int -> Double and omit the unsafePerformIO. Cheers, Manuel _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

On Thu, Oct 16, 2003 at 11:26:11AM +0200, Andreas.Schroeder@gillardon.de wrote:
1. how can i do performance tests if the tests are small? In imperative languages, you cycle through 1000 times and divide the runtime by 1000. How can i do something similar in haskell?
Even in an imperative language, running a fast calculation in a loop is a fishy way to run a timing. I'd say that whatever sort of language you're using, the best way to run a timing is always in the context of how you plan to actually use the routine. If it's so fast that you can't distinguish its time from that spent in the calling routine, it means you don't need to bother optimizing it. That being said, you you can pretty easily use map and fold to run a function a number of times and actually used. Whether you're using a functional language or an imperative one, in the presense of sufficiently smart compilers you always have to make sure your result is actually used in some way--otherwise the compiler could just skip the loop. In a lazy language like haskell, even if the compiler isn't smart, if the results aren't used it'll probably skip the loop. slow_function :: Double -> Double test max = sum $ map slow_function [0.0,0.001..max]
2. How do i get haskell to do something _without_ printing anything on the screen? For now, i do something like
main = do startt <- getCPUTime putStr $ (show testAIBD1) ++ ", " ++ (show testZins1) endt <- getCPUTime putStr $ "\tTook " ++ (show $ (endt - startt) `div` ((10^6) * 5)) ++ " ns\n"
where testAIBD1 is a sum of 40 calculation results and also is testZins1.
main = do startt <- getCPUTime when (testAIBD1 == a value) $ exitWith ExitSuccess when (testZins1 == a value) $ exitWith ExitSuccess endt <- getCPUTime putStr $ "\tTook " ++ (show $ (endt - startt) `div` ((10^6) * 5)) ++ "ns\n" Except that you probably need to give an input via the IO monad to testAIBD1, otherwise the compiler can determine at compile time that the equality is false and not bother generating any code for it. -- David Roundy http://www.abridgegame.org/darcs
participants (2)
-
Andreas.Schroeder@gillardon.de
-
David Roundy