packages feed

alignment-0.2.0.1: bench/ZipUnzip.hs

{-# LANGUAGE ScopedTypeVariables #-}

{- HLINT ignore "Avoid NonEmpty.unzip" -}

module Main where

import Control.DeepSeq (force)
import Criterion.Main
import Data.Alignment
import qualified Data.Alignment as A
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import qualified Data.Vector as V
import Prelude (IO, Int, uncurry, ($))
import qualified Prelude as P

main :: IO ()
main =
  defaultMain
    [ zipBenchmarks,
      unzipBenchmarks
    ]

zipBenchmarks :: Benchmark
zipBenchmarks =
  bgroup
    "zip: Data.Alignment vs Base"
    [ bgroup
        "lists/equal"
        [ bench "Prelude.zip 100" $ nf (P.uncurry P.zip) (listPair 100),
          bench "A.zip 100" $ nf (P.uncurry A.zip) (listPair 100),
          bench "Prelude.zip 1000" $ nf (P.uncurry P.zip) (listPair 1000),
          bench "A.zip 1000" $ nf (P.uncurry A.zip) (listPair 1000),
          bench "Prelude.zip 10000" $ nf (P.uncurry P.zip) (listPair 10000),
          bench "A.zip 10000" $ nf (P.uncurry A.zip) (listPair 10000)
        ],
      bgroup
        "lists/unequal"
        [ bench "Prelude.zip 100/50" $ nf (\(xs, ys) -> P.zip xs (P.take 50 ys)) (listPair 100),
          bench "A.zip 100/50" $ nf (\(xs, ys) -> A.zip xs (P.take 50 ys)) (listPair 100),
          bench "Prelude.zip 1000/500" $ nf (\(xs, ys) -> P.zip xs (P.take 500 ys)) (listPair 1000),
          bench "A.zip 1000/500" $ nf (\(xs, ys) -> A.zip xs (P.take 500 ys)) (listPair 1000),
          bench "Prelude.zip 10000/5000" $ nf (\(xs, ys) -> P.zip xs (P.take 5000 ys)) (listPair 10000),
          bench "A.zip 10000/5000" $ nf (\(xs, ys) -> A.zip xs (P.take 5000 ys)) (listPair 10000)
        ],
      bgroup
        "vectors"
        [ bench "V.zip 100" $ nf (P.uncurry V.zip) (vectorPair 100),
          bench "A.zip 100" $ nf (P.uncurry A.zip) (vectorPair 100),
          bench "V.zip 1000" $ nf (P.uncurry V.zip) (vectorPair 1000),
          bench "A.zip 1000" $ nf (P.uncurry A.zip) (vectorPair 1000),
          bench "V.zip 10000" $ nf (P.uncurry V.zip) (vectorPair 10000),
          bench "A.zip 10000" $ nf (P.uncurry A.zip) (vectorPair 10000)
        ],
      bgroup
        "NonEmpty"
        [ bench "NE.zip 100" $ nf (P.uncurry NE.zip) (nePair 100),
          bench "A.zip 100" $ nf (P.uncurry A.zip) (nePair 100),
          bench "NE.zip 1000" $ nf (P.uncurry NE.zip) (nePair 1000),
          bench "A.zip 1000" $ nf (P.uncurry A.zip) (nePair 1000)
        ]
    ]

unzipBenchmarks :: Benchmark
unzipBenchmarks =
  bgroup
    "unzip: Data.Alignment vs Base"
    [ bgroup
        "lists"
        [ bench "Prelude.unzip 100" $ nf P.unzip (pairList 100),
          bench "A.unzip 100" $ nf A.unzip (pairList 100),
          bench "Prelude.unzip 1000" $ nf P.unzip (pairList 1000),
          bench "A.unzip 1000" $ nf A.unzip (pairList 1000),
          bench "Prelude.unzip 10000" $ nf P.unzip (pairList 10000),
          bench "A.unzip 10000" $ nf A.unzip (pairList 10000)
        ],
      bgroup
        "vectors"
        [ bench "V.unzip 100" $ nf V.unzip (V.fromList $ pairList 100),
          bench "A.unzip 100" $ nf A.unzip (V.fromList $ pairList 100),
          bench "V.unzip 1000" $ nf V.unzip (V.fromList $ pairList 1000),
          bench "A.unzip 1000" $ nf A.unzip (V.fromList $ pairList 1000),
          bench "V.unzip 10000" $ nf V.unzip (V.fromList $ pairList 10000),
          bench "A.unzip 10000" $ nf A.unzip (V.fromList $ pairList 10000)
        ],
      bgroup
        "NonEmpty"
        [ bench "NE.unzip 100" $ nf NE.unzip (neList 100),
          bench "A.unzip 100" $ nf A.unzip (neList 100),
          bench "NE.unzip 1000" $ nf NE.unzip (neList 1000),
          bench "A.unzip 1000" $ nf A.unzip (neList 1000)
        ]
    ]

-- Test data generators
listPair :: Int -> ([Int], [Int])
listPair n = ([1 .. n], [1 .. n])

vectorPair :: Int -> (V.Vector Int, V.Vector Int)
vectorPair n = (V.enumFromN 1 n, V.enumFromN 1 n)

nePair :: Int -> (NonEmpty Int, NonEmpty Int)
nePair n = (1 :| [2 .. n], 1 :| [2 .. n])

pairList :: Int -> [(Int, Int)]
pairList n = [(i, i) | i <- [1 .. n]]

neList :: Int -> NonEmpty (Int, Int)
neList n = (1, 1) :| [(i, i) | i <- [2 .. n]]