Bryan O'Sullivan avatar Bryan O'Sullivan committed 28e0ab6

Add a few simple apples-to-apples formatting benchmarks.

Comments (0)

Files changed (8)

 ^(?:cabal-dev|dist)$
-^tests/bm$
+^benchmarks/(?:bm|simple|sprintf|swprintf)$
 \.(?:aux|eventlog|h[ip]|log|[oa]|orig|prof|ps|rej|swp)$
 ~$
 syntax: glob

benchmarks/Benchmarks.hs

+{-# LANGUAGE OverloadedStrings #-}
+
+import Criterion.Main
+import Data.Text.Format
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as L
+
+main = defaultMain [
+         bgroup "arity" [
+           bench "0" $ nf (format "hi") ()
+         , bench "1" $ nf (format "hi {}") (Only $ T.pack "mom")
+         , bench "2" $ nf (format "hi {}, how are {}")
+                       (T.pack "mom", T.pack "you")
+         , bench "3" $ nf (format "hi {}, how are {} keeping {}")
+                       (T.pack "mom", T.pack "you", T.pack "now")
+         , bench "4" $ nf (format "hi {}, {} - how are {} keeping {}")
+                       (T.pack "mom", T.pack "hey", T.pack "you", T.pack "now")
+         ]
+       , bgroup "types" [
+           bench "unit" $ nf (format "hi") ()
+         , bgroup "int" [
+             bench "small" $ nf (format "hi {}") (Only (1::Int))
+           , bench "medium" $ nf (format "hi {}") (Only (1234::Int))
+           , bench "large" $ nf (format "hi {}") (Only (0x7fffffff::Int))
+           ]
+         , bgroup "float" [
+             bgroup "slow" [
+               bench "small" $ nf (format "hi {}") (Only (1::Float))
+             , bench "medium" $ nf (format "hi {}") (Only (pi::Float))
+             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Float))
+             ]
+           , bgroup "fast" [
+               bench "small" $ nf (format "hi {}") (Only (1::Fast Float))
+             , bench "medium" $ nf (format "hi {}") (Only (pi::Fast Float))
+             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Fast Float))
+             ]
+           ]
+         , bgroup "double" [
+             bgroup "slow" [
+               bench "small" $ nf (format "hi {}") (Only (1::Double))
+             , bench "medium" $ nf (format "hi {}") (Only (pi::Double))
+             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Double))
+             ]
+           , bgroup "fast" [
+               bench "small" $ nf (format "hi {}") (Only (1::Fast Double))
+             , bench "medium" $ nf (format "hi {}") (Only (pi::Fast Double))
+             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Fast Double))
+             ]
+           ]
+         , bgroup "string" [
+             bench "small" $ nf (format "hi {}") (Only ("mom" :: String))
+           , bench "medium" $ nf (format "hi {}")
+                              (Only . concat . replicate 64 $ ("mom" :: String))
+           , bench "large" $ nf (format "hi {}")
+                             (Only . concat . replicate 1024 $ ("mom" :: String))
+           ]
+         , bgroup "text" [
+             bench "small" $ nf (format "hi {}") (Only (T.pack "mom"))
+           , bench "medium" $ nf (format "hi {}") (Only (T.replicate 64 "mom"))
+           , bench "large" $ nf (format "hi {}") (Only (T.replicate 1024 "mom"))
+           ]
+           , bgroup "lazytext" [
+               bench "small" $ nf (format "hi {}") (Only (L.pack "mom"))
+             , bench "medium" $ nf (format "hi {}")
+                                (Only . L.fromChunks . replicate 64 $ "mom")
+             , bench "large" $ nf (format "hi {}")
+                               (Only . L.fromChunks . replicate 1024 $ "mom")
+             ]
+           ]
+         ]

benchmarks/Makefile

+ghc := ghc
+
+programs := bm simple sprintf swprintf
+
+all: $(programs)
+
+bm: Benchmarks.hs
+	$(ghc) -rtsopts -O -o $@ $<
+
+simple: Simple.hs
+	$(ghc) -rtsopts -O -o $@ $<
+
+sprintf: sprintf.c
+	$(CC) -O2 -o $@ $<
+
+swprintf: swprintf.c
+	$(CC) -O2 -o $@ $<
+
+clean:
+	-rm -f $(programs) *.hi *.o *.hp

benchmarks/Simple.hs

+{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+
+import Control.Monad
+import System.Environment
+import qualified Data.Text.Format as T
+import Data.Time.Clock
+
+main = do
+  args <- getArgs
+  let count = case args of
+                (x:_) -> read x :: Int
+                _     -> 100000
+  start <- getCurrentTime
+  forM_ [0..count] $ \i -> do
+    let !t = T.format "hi mom {}\n" [fromIntegral i * pi::Double]
+    return ()
+  elapsed <- (`diffUTCTime` start) `fmap` getCurrentTime
+  T.print "{} iterations in {} secs ({} thousand/sec\n"
+       (count, elapsed,
+        fromRational (toRational count / toRational elapsed / 1e3) :: Double)

benchmarks/sprintf.c

+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+double gettime(void)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+
+    return tv.tv_sec + (tv.tv_usec / 1e6);
+}
+
+void loop(int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+	char *s = malloc(64);
+
+	sprintf(s, "hi mom %g\n", (double) i * M_PI);
+
+	free(s);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    double start, elapsed;
+    int i, count;
+
+    count = argc == 2 ? atoi(argv[1]) : 1600000;
+
+    start = gettime();
+    
+    loop(count);
+
+    elapsed = gettime() - start;
+
+    printf("%d iterations in %g secs (%g thousand/sec)\n", count, elapsed,
+	   count / elapsed / 1e3);
+}

benchmarks/swprintf.c

+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <wchar.h>
+
+double gettime(void)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+
+    return tv.tv_sec + (tv.tv_usec / 1e6);
+}
+
+void loop(int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+	wchar_t *s = malloc(64 * sizeof(wchar_t));
+
+	swprintf(s, 64, L"hi mom %g\n", (double) i * M_PI);
+
+	free(s);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    double start, elapsed;
+    int i, count;
+
+    count = argc == 2 ? atoi(argv[1]) : 1600000;
+
+    start = gettime();
+    
+    loop(count);
+
+    elapsed = gettime() - start;
+
+    printf("%d iterations in %g secs (%g thousand/sec)\n", count, elapsed,
+	   count / elapsed / 1e3);
+}

tests/Benchmarks.hs

-{-# LANGUAGE OverloadedStrings #-}
-
-import Criterion.Main
-import Data.Text.Format
-import qualified Data.Text as T
-import qualified Data.Text.Lazy as L
-
-main = defaultMain [
-         bgroup "arity" [
-           bench "0" $ nf (format "hi") ()
-         , bench "1" $ nf (format "hi {}") (Only $ T.pack "mom")
-         , bench "2" $ nf (format "hi {}, how are {}")
-                       (T.pack "mom", T.pack "you")
-         , bench "3" $ nf (format "hi {}, how are {} keeping {}")
-                       (T.pack "mom", T.pack "you", T.pack "now")
-         , bench "4" $ nf (format "hi {}, {} - how are {} keeping {}")
-                       (T.pack "mom", T.pack "hey", T.pack "you", T.pack "now")
-         ]
-       , bgroup "types" [
-           bench "unit" $ nf (format "hi") ()
-         , bgroup "int" [
-             bench "small" $ nf (format "hi {}") (Only (1::Int))
-           , bench "medium" $ nf (format "hi {}") (Only (1234::Int))
-           , bench "large" $ nf (format "hi {}") (Only (0x7fffffff::Int))
-           ]
-         , bgroup "float" [
-             bgroup "slow" [
-               bench "small" $ nf (format "hi {}") (Only (1::Float))
-             , bench "medium" $ nf (format "hi {}") (Only (pi::Float))
-             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Float))
-             ]
-           , bgroup "fast" [
-               bench "small" $ nf (format "hi {}") (Only (1::Fast Float))
-             , bench "medium" $ nf (format "hi {}") (Only (pi::Fast Float))
-             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Fast Float))
-             ]
-           ]
-         , bgroup "double" [
-             bgroup "slow" [
-               bench "small" $ nf (format "hi {}") (Only (1::Double))
-             , bench "medium" $ nf (format "hi {}") (Only (pi::Double))
-             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Double))
-             ]
-           , bgroup "fast" [
-               bench "small" $ nf (format "hi {}") (Only (1::Fast Double))
-             , bench "medium" $ nf (format "hi {}") (Only (pi::Fast Double))
-             , bench "large" $ nf (format "hi {}") (Only (pi*1e37::Fast Double))
-             ]
-           ]
-         , bgroup "string" [
-             bench "small" $ nf (format "hi {}") (Only ("mom" :: String))
-           , bench "medium" $ nf (format "hi {}")
-                              (Only . concat . replicate 64 $ ("mom" :: String))
-           , bench "large" $ nf (format "hi {}")
-                             (Only . concat . replicate 1024 $ ("mom" :: String))
-           ]
-         , bgroup "text" [
-             bench "small" $ nf (format "hi {}") (Only (T.pack "mom"))
-           , bench "medium" $ nf (format "hi {}") (Only (T.replicate 64 "mom"))
-           , bench "large" $ nf (format "hi {}") (Only (T.replicate 1024 "mom"))
-           ]
-           , bgroup "lazytext" [
-               bench "small" $ nf (format "hi {}") (Only (L.pack "mom"))
-             , bench "medium" $ nf (format "hi {}")
-                                (Only . L.fromChunks . replicate 64 $ "mom")
-             , bench "large" $ nf (format "hi {}")
-                               (Only . L.fromChunks . replicate 1024 $ "mom")
-             ]
-           ]
-         ]

tests/Makefile

-ghc := ghc
-
-all: bm
-
-bm: Benchmarks.hs
-	$(ghc) -rtsopts -O -o $@ $<
-
-clean:
-	-rm -f bm *.hi *.o *.hp
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.