Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Linux realtime clock Haskell FFI timings
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Bench where
import Control.Monad
import Criterion.Main
import Foreign
import Foreign.C.Types
#include <time.h>
data TimeSpec = TimeSpec {
tvSec :: {-# UNPACK #-} !CTime
, tvUSec :: {-# UNPACK #-} !CLong
}
instance Storable TimeSpec where
sizeOf _ = (#size struct timespec)
alignment _ = alignment (undefined :: CLong)
peek ptr = do
sec <- (#peek struct timespec, tv_sec) ptr
usec <- (#peek struct timespec, tv_nsec) ptr
return $! TimeSpec sec usec
poke ptr (TimeSpec sec usec) = do
(#poke struct timespec, tv_sec) ptr sec
(#poke struct timespec, tv_nsec) ptr usec
foreign import ccall unsafe "coarse_monotonic_time"
c_coarse_monotonic_time :: Ptr TimeSpec -> IO ()
foreign import ccall unsafe "monotonic_time"
c_monotonic_time :: Ptr TimeSpec -> IO ()
foreign import ccall unsafe "coarse_realtime_time"
c_coarse_realtime_time :: Ptr TimeSpec -> IO ()
foreign import ccall unsafe "realtime_time"
c_realtime_time :: Ptr TimeSpec -> IO ()
foreign import ccall unsafe "cpu_time"
c_cpu_time :: Ptr TimeSpec -> IO ()
coarseMonotonicTime :: IO TimeSpec
coarseMonotonicTime = alloca $ \ptr -> c_coarse_monotonic_time ptr >> peek ptr
monotonicTime :: IO TimeSpec
monotonicTime = alloca $ \ptr -> c_monotonic_time ptr >> peek ptr
coarseRealtimeTime :: IO TimeSpec
coarseRealtimeTime = alloca $ \ptr -> c_coarse_realtime_time ptr >> peek ptr
realtimeTime :: IO TimeSpec
realtimeTime = alloca $ \ptr -> c_realtime_time ptr >> peek ptr
cpuTime :: IO TimeSpec
cpuTime = alloca $ \ptr -> c_cpu_time ptr >> peek ptr
main :: IO ()
main = defaultMain [ bench "coarseMonotonic" $! replicateM_ 1000 $! whnfIO coarseMonotonicTime
, bench "monotonic" $! replicateM_ 1000 $! whnfIO monotonicTime
, bench "coarseRealtime" $! replicateM_ 1000 $! whnfIO coarseRealtimeTime
, bench "realtime" $! replicateM_ 1000 $! whnfIO realtimeTime
, bench "cpu" $! replicateM_ 1000 $! whnfIO cpuTime
]
warming up
estimating clock resolution...
mean is 1.409399 us (640001 iterations)
found 1130 outliers among 639999 samples (0.2%)
375 (5.9e-2%) high severe
estimating cost of a clock call...
mean is 74.24951 ns (14 iterations)
found 3 outliers among 14 samples (21.4%)
3 (21.4%) high severe
benchmarking coarseMonotonic
mean: 15.60754 us, lb 15.48935 us, ub 15.83506 us, ci 0.950
std dev: 810.5768 ns, lb 493.4896 ns, ub 1.255423 us, ci 0.950
found 11 outliers among 100 samples (11.0%)
10 (10.0%) high severe
variance introduced by outliers: 50.434%
variance is severely inflated by outliers
benchmarking monotonic
mean: 25.00275 us, lb 24.93672 us, ub 25.10655 us, ci 0.950
std dev: 418.0586 ns, lb 296.7698 ns, ub 594.0569 ns, ci 0.950
found 11 outliers among 100 samples (11.0%)
4 (4.0%) high mild
7 (7.0%) high severe
variance introduced by outliers: 9.441%
variance is slightly inflated by outliers
benchmarking coarseRealtime
mean: 14.47882 us, lb 14.40141 us, ub 14.75364 us, ci 0.950
std dev: 666.4898 ns, lb 186.6437 ns, ub 1.520402 us, ci 0.950
found 7 outliers among 100 samples (7.0%)
3 (3.0%) high mild
4 (4.0%) high severe
variance introduced by outliers: 44.440%
variance is moderately inflated by outliers
benchmarking realtime
mean: 24.92609 us, lb 24.84392 us, ub 25.10949 us, ci 0.950
std dev: 597.2018 ns, lb 336.7450 ns, ub 1.139590 us, ci 0.950
found 11 outliers among 100 samples (11.0%)
4 (4.0%) high mild
7 (7.0%) high severe
variance introduced by outliers: 17.118%
variance is moderately inflated by outliers
benchmarking cpu
mean: 195.0717 us, lb 193.8936 us, ub 200.4477 us, ci 0.950
std dev: 11.01044 us, lb 1.365705 us, ub 26.10516 us, ci 0.950
found 4 outliers among 100 samples (4.0%)
3 (3.0%) high mild
1 (1.0%) high severe
variance introduced by outliers: 54.462%
variance is severely inflated by outliers
#include <time.h>
void coarse_monotonic_time(struct timespec *res) {
(void) clock_gettime(CLOCK_MONOTONIC_COARSE, res);
}
void monotonic_time(struct timespec *res) {
(void) clock_gettime(CLOCK_MONOTONIC, res);
}
void coarse_realtime_time(struct timespec *res) {
(void) clock_gettime(CLOCK_REALTIME_COARSE, res);
}
void realtime_time(struct timespec *res) {
(void) clock_gettime(CLOCK_REALTIME, res);
}
void cpu_time(struct timespec *res) {
(void) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, res);
}