{-# LANGUAGE AllowAmbiguousTypes, TypeApplications, DerivingStrategies #-} module Main where import UnliftIO.Internals.Async import System.Environment (getArgs) import Test.QuickCheck import Prettyprinter import Control.Monad.Credit import Test.Credit import Test.Credit.Queue.Base import Test.Credit.Queue.Batched import Test.Credit.Queue.Bankers import Test.Credit.Queue.Physicists import Test.Credit.Queue.Realtime import Test.Credit.Queue.Bootstrapped import Test.Credit.Queue.Implicit import Test.Credit.Deque.Base import Test.Credit.Deque.Bankers import Test.Credit.Deque.Realtime import Test.Credit.Deque.Catenable import Test.Credit.Deque.SimpleCat import Test.Credit.Deque.ImplicitCat import Test.Credit.Finger import Test.Credit.Heap.Base import Test.Credit.Heap.Binomial import Test.Credit.Heap.LazyPairing import Test.Credit.Heap.Scheduled import Test.Credit.Sortable.Base import Test.Credit.Sortable.MergeSort import Test.Credit.Sortable.Scheduled import Test.Credit.RandomAccess.Base import Test.Credit.RandomAccess.Binary import Test.Credit.RandomAccess.Zeroless run :: forall t op. (MemoryStructure t, DataStructure t op) => Args -> Strategy -> IO Result run args strat = quickCheckWithResult args $ checkCreditsMemory @t strat newtype Alpha = Alpha Char deriving (Eq, Ord) deriving newtype (Pretty) instance Show Alpha where show (Alpha c) = [c] instance Arbitrary Alpha where arbitrary = Alpha <$> frequency [ (1, choose ('a', 'z')), (1, choose ('A', 'Z')) ] benchmarks :: Args -> [(String, IO Result)] benchmarks args = [ (benchs ++ strats ++ ":", runB args strat) | (strats, strat) <- [ (" (path)", Path) , (" (bloom)", Bloom) , (" (pennant)", Pennant) , (" (random)", Random) ] , (benchs, runB) <- reverse [ ("Batched Queue", run @(Q Batched Alpha)) , ("Bankers Queue", run @(Q BQueue Alpha)) , ("Physicists Queue", run @(Q Physicists Alpha)) , ("Realtime Queue", run @(Q RQueue Alpha)) , ("Bootstrapped Queue", run @(Q Bootstrapped Alpha)) , ("Implicit Queue", run @(Q Implicit Alpha)) , ("Bankers Deque", run @(D BDeque Alpha)) , ("Realtime Deque", run @(D RDeque Alpha)) , ("Catenable List", run @(D CatDeque Alpha)) , ("Simple Catenable Deque", run @(D SimpleCat Alpha)) , ("Implicit Catenable Deque", run @(D ImplicitCat Alpha)) , ("Catenable List (Concat)", run @(BD CatDeque Alpha)) , ("Simple Catenable Deque (Concat)", run @(BD SimpleCat Alpha)) , ("Implicit Catenable Deque (Concat)", run @(BD ImplicitCat Alpha)) , ("Binomial Heap", run @(H Binomial Alpha)) , ("Lazy Pairing Heap", run @(H LazyPairing Alpha)) , ("Scheduled Binomial Heap", run @(H Scheduled Alpha)) , ("Binomial Heap (Merge)", run @(BH Binomial Alpha)) , ("Lazy Pairing Heap (Merge)", run @(BH LazyPairing Alpha)) , ("Scheduled Binomial Heap (Merge)", run @(BH Scheduled Alpha)) , ("Mergesort", run @(S MergeSort Alpha)) , ("Scheduled Mergesort", run @(S SMergeSort Alpha)) , ("Binary Random Access List", run @(RA BinaryRA Alpha)) , ("Zeroless Random Access List", run @(RA ZerolessRA Alpha)) , ("Finger Tree (Deque)", run @(D FingerDeque Alpha)) , ("Finger Tree (Concat)", run @(BD FingerDeque Alpha)) , ("Finger Tree (Heap)", run @(H FingerHeap Alpha)) , ("Finger Tree (Merge)", run @(BH FingerHeap Alpha)) , ("Finger Tree (Random Access)", run @(RA FingerRA Alpha)) , ("Finger Tree (Sortable)", run @(S FingerSort Alpha)) ] ] main :: IO () main = do (maxSuccess, maxSize) <- do args <- getArgs case args of [n, s] -> pure (read n, read s) [n] -> pure (read n, 1000) _ -> pure (1000, 1000) let args = stdArgs { maxSuccess, maxSize, maxShrinks = maxBound, chatty = False } pooledForConcurrently_ (benchmarks args) $ \(s,r) -> do res <- r putStrLn $ s ++ "\n" ++ output res -- Categorization of implementations: -- Passing static credits to static reference: -- - Realtime Queue (Section 7.2) -- - Realtime Deque (Section 8.4.3) -- - Scheduled Binomial Heaps (Section 7.3) -- - Scheduled Mergesort (Section 7.4) -- Passing static credits to dynamic reference: -- - Implicit Queue (Section 11.1) -- - Binary Random Access List (Section 9.2.3) -- - Zeroless Random Access List (Section 9.2.3) -- - Finger Tree -- - Simple Catenable Deque (Section 11.2) -- - Implicit Catenable Deque (Section 11.2) -- Passing dynamic credits to static reference: -- - Binomial Heaps (Section 6.4.1) -- - Lazy Pairing Heaps (Section 6.5) -- - Bottom-up Mergesort (Section 6.4.3) -- Passing static credits to ghost reference: -- - Bootstrapped Queue (Section 10.1.3) -- - Physicists Queue (Section 6.4.2) -- Requires extra traversal: -- - Catenable List (Section 10.2.1) -- Needs Credit Inheritance: -- - Bankers Queue (Section 6.3.2) -- - Bankers Deque (Section 8.4.2)