{-# LANGUAGE BangPatterns #-} module Timer (timer) where import Control.Exception (
evaluate
) import Data.Time.Clock.POSIX (
getPOSIXTime
) import
GHC.Float
(FFFormat(..), formatRealFloat)
ickyRound
::
Int
->
Double
->
String
ickyRound
k
=
formatRealFloat
FFFixed
(
Just
k
)
timer
::
Int
->
a
-> (
a
->
b
) ->
IO
String
timer
count
a0
f
= do let
loop
!
k
!
fastest
|
k
<=
0
=
return
fastest
|
otherwise
= do
start
<-
getPOSIXTime
let
inner
a
i
|
i
<=
0
=
return
()
|
otherwise
=
evaluate
(
f
a
)
>>
inner
a
(
i
-
1
)
inner
a0
count
end
<-
getPOSIXTime
let
elapsed
=
end
-
start
loop
(
k
-
1
) (
min
fastest
(
elapsed
/
fromIntegral
count
))
t
<-
loop
(
3
::
Int
)
1e300
let
log10
x
=
log
x
/
log
10
ft
=
realToFrac
t
prec
=
round
(
log10
(
fromIntegral
count
)
-
log10
ft
)
return
$!
ickyRound
prec
ft
{-# NOINLINE
timer
#-}