Performance Tests in Haskell

Andreas.Schroeder at gillardon.de Andreas.Schroeder at gillardon.de
Thu Oct 16 12:26:11 EDT 2003


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 at gillardon.de|
|         |           Gesendet von:                 |
|         |           glasgow-haskell-users-bounces@|
|         |           haskell.org                   |
|         |                                         |
|         |                                         |
|         |           16.10.2003 09:37              |
|         |                                         |
|---------+----------------------------------------->
  >-------------------------------------------------------------------------------------------------------------------|
  |                                                                                                                   |
  |        An:      glasgow-haskell-users at haskell.org                                                                 |
  |        Kopie:   chak at 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        |
|         |           <chak at cse.unsw.edu.au>        |
|         |           Gesendet von:                 |
|         |           glasgow-haskell-users-bounces@|
|         |           haskell.org                   |
|         |                                         |
|         |                                         |
|         |           16.10.2003 07:02              |
|         |           Bitte antworten an chak       |
|         |                                         |
|---------+----------------------------------------->
  >
-------------------------------------------------------------------------------------------------------------------|

  |
|
  |        An:      Andreas.Schroeder at gillardon.de
|
  |        Kopie:   glasgow-haskell-users at haskell.org
|
  |        Thema:   Re: GHC with MS .Net 2003 C compiler
|
  >
-------------------------------------------------------------------------------------------------------------------|




Andreas.Schroeder at 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#AEN5918



> 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 at haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users at haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users







More information about the Glasgow-haskell-users mailing list