Commits

Bryan O'Sullivan  committed 5ad5391

Benchmark stdio functions via the FFI

  • Participants
  • Parent commits 2e0ca11

Comments (0)

Files changed (3)

File benchmarks/Benchmarks.hs

-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}
 
 import Criterion.Main
 import Data.Double.Conversion
+import Foreign.C.Types (CInt, CDouble)
 import qualified Data.Text as T
 
 showText :: Double -> T.Text
 showText d = T.pack (show d)
 
 main = defaultMain [
-         bench "show" $ whnf showText pi
-       , bench "toShortest" $ whnf toShortest pi
-       , bench "toExponential" $ whnf (toExponential 3) pi
-       , bench "toPrecision" $ whnf (toExponential 8) pi
-       , bench "toFixed" $ whnf (toFixed 8) pi
+         bgroup "haskell" [
+           bench "show" $ whnf showText pi
+         , bench "toShortest" $ whnf toShortest pi
+         , bench "toExponential" $ whnf (toExponential 3) pi
+         , bench "toPrecision" $ whnf (toExponential 8) pi
+         , bench "toFixed" $ whnf (toFixed 8) pi
+         ]
+       , bgroup "sprintf" [
+           bench "exponential" $ whnf (sprintf_exponential 3) pi
+         , bench "fixed" $ whnf (sprintf_fixed 8) pi
+         , bench "generic" $ whnf (sprintf_generic 6) pi
+         , bench "generic_default" $ whnf (sprintf_generic_default 6) pi
+         ]
        ]
+
+foreign import ccall safe sprintf_exponential :: CInt -> CDouble -> ()
+foreign import ccall safe sprintf_fixed :: CInt -> CDouble -> ()
+foreign import ccall safe sprintf_generic :: CInt -> CDouble -> ()
+foreign import ccall safe sprintf_generic_default :: CInt -> CDouble -> ()

File benchmarks/double-conversion-benchmarks.cabal

 executable bm
   main-is: Benchmarks.hs
 
+  c-sources: sprintf.c
+
   build-depends:
     base,
     criterion >= 0.5.0.10,

File benchmarks/sprintf.c

+#include <stdio.h>
+
+void sprintf_exponential(int d, double x)
+{
+  char buf[64];
+  snprintf(buf, 64, "%*e", d, x);
+}
+
+void sprintf_fixed(int d, double x)
+{
+  char buf[64];
+  snprintf(buf, 64, "%*f", d, x);
+}
+
+void sprintf_generic(int d, double x)
+{
+  char buf[64];
+  snprintf(buf, 64, "%*g", d, x);
+}
+
+void sprintf_generic_default(double x)
+{
+  char buf[64];
+  snprintf(buf, 64, "%g", x);
+}