From 40054ebad805d52407e0899d0e591a2d70ca7cf3 Mon Sep 17 00:00:00 2001 From: Li-yao Xia Date: Sun, 17 Mar 2024 11:53:27 +0100 Subject: [PATCH] Use bcompareWithin to automate tests for linear time complexity --- benchmarks/haskell/Benchmarks/Micro.hs | 28 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/benchmarks/haskell/Benchmarks/Micro.hs b/benchmarks/haskell/Benchmarks/Micro.hs index 5462393a..511e17fa 100644 --- a/benchmarks/haskell/Benchmarks/Micro.hs +++ b/benchmarks/haskell/Benchmarks/Micro.hs @@ -4,19 +4,29 @@ module Benchmarks.Micro (benchmark) where import qualified Data.Text.Lazy as TL import qualified Data.Text as T -import Test.Tasty.Bench (Benchmark, bgroup, bench, nf) +import Test.Tasty.Bench (Benchmark, Benchmarkable, bgroup, bcompareWithin, bench, nf) benchmark :: Benchmark benchmark = bgroup "Micro" - [ -- Accessing i-th element should take O(i) time. - -- The 2k case should run in 2x the time of the 1k case. - bgroup "Lazy.inits" - [ bench "last 1k" $ nf (last . TL.inits) (chunks 1000) - , bench "last 2k" $ nf (last . TL.inits) (chunks 2000) - , bench "map-take1 1k" $ nf (map (TL.take 1) . TL.inits) (chunks 1000) - , bench "map-take1 2k" $ nf (map (TL.take 1) . TL.inits) (chunks 2000) - ] + [ blinear "lazy-inits--last" 500000 2 0.1 $ \len -> + nf (last . TL.inits) (chunks len) + , blinear "lazy-inits--map-take1" 500000 2 0.1 $ \len -> + nf (map (TL.take 1) . TL.inits) (chunks len) ] chunks :: Int -> TL.Text chunks n = TL.fromChunks (replicate n (T.pack "a")) + +-- Check that running an action with input length (m * baseLen) +-- runs m times slower than the same action with input length baseLen. +blinear :: String -- ^ Name (must be globally unique!) + -> Int -- ^ Base length + -> Int -- ^ Multiplier m + -> Double -- ^ Slack s + -> (Int -> Benchmarkable) -- ^ Action to measure, parameterized by input length + -> Benchmark +blinear name baseLen m s run = bgroup name + [ bench "baseline" $ run baseLen + , bcompareWithin (fromIntegral m * (1 - s)) (fromIntegral m * (1 + s)) (name ++ ".baseline") $ + bench ("x" ++ show m) $ run (m * baseLen) + ]