module Algorithms.Geometry.ClosestPair.Bench where import qualified Algorithms.Geometry.ClosestPair.DivideAndConquer as DivideAndConquer import qualified Algorithms.Geometry.ClosestPair.Naive as Naive import Benchmark.Util import Control.DeepSeq import Criterion.Main import Criterion.Types import Data.Ext import Data.Geometry.Point import Data.Proxy import Test.QuickCheck import Test.QuickCheck.HGeometryInstances () import Data.LSeq (LSeq) import qualified Data.LSeq as LSeq -------------------------------------------------------------------------------- main :: IO () main = defaultMainWith cfg [ benchmark ] where cfg = defaultConfig { reportFile = Just "bench.html" } benchmark :: Benchmark benchmark = bgroup "convexHullBench" [ env (genPts (Proxy :: Proxy Int) 10000) benchBuild ] -------------------------------------------------------------------------------- genPts :: (Ord r, Arbitrary r) => proxy r -> Int -> IO (LSeq 2 (Point 2 r :+ ())) genPts _ n | n >= 2 = generate (LSeq.promise . LSeq.fromList <$> vectorOf n arbitrary) | otherwise = error "genPts: Need at least 2 points" -- | Benchmark computing the closest pair benchBuild :: (Ord r, Num r, NFData r) => LSeq 2 (Point 2 r :+ ()) -> Benchmark benchBuild ps = bgroup "closestPair" [ bgroup (show n) (build $ take' n ps) | n <- sizes' ps ] where take' n = LSeq.promise . LSeq.take n sizes' pts = let n = length pts in [ n*i `div` 100 | i <- [10,20,25,50,75,100]] build pts = [ bench "sort" $ nf LSeq.unstableSort pts , bench "Div&Conq" $ nf DivideAndConquer.closestPair pts , bench "Naive" $ nf Naive.closestPair pts ]