packages feed

short-vec-0.1.0.0: test/Benchmark.hs

-- Copyright 2018-2021 Google LLC
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}

module Main where

import Prelude hiding ((++))

import Control.Applicative (liftA2, liftA3)
import Control.Exception (evaluate)
import Data.Foldable (foldl', foldr', toList)
import Data.Semigroup (Sum(..))

import Control.DeepSeq (force)
import Data.Vec.Short
import Data.Fin.Int (fin, finToInt, modNegate)
import Data.Functor.WithIndex (FunctorWithIndex(..))

import qualified Gauge as G

theAnswer :: Vec 64 Int
theAnswer = pure 42

benchForce_DeepSeq
  , benchPure, benchRot
  , benchMap, benchMapId, benchMapCoerce, benchMap2
  , benchSum, benchSumMap
  , benchFoldr, benchFoldr1, benchFoldr', benchFoldl, benchFoldl1, benchFoldl'
  , benchAppend, benchAppendMap
  , benchTraverseIO
  , benchLiftA2
  , benchConvolve
  , benchMapWithPos
  , benchMapToList, benchMapToListMap, benchSumToListMap
  , benchEq_true, benchEq_false
  , benchTake, benchMapTake, benchDrop, benchMapDrop
  , benchSplit
  :: G.Benchmark

benchForce_DeepSeq = G.bench "force_DeepSeq" $ G.whnf force theAnswer
benchPure = G.bench "pure" $ G.whnf (pure :: Int -> Vec 64 Int) 42
benchMap = G.bench "map" $ G.whnf (map' (+2)) theAnswer
benchMapId = G.bench "mapId" $ G.whnf (fmap id) theAnswer
benchMapCoerce = G.bench "mapCoerce" $ G.whnf (fmap Sum) theAnswer
benchMap2 = G.bench "map2" $ G.whnf (map' (+2) . fmap (+2)) theAnswer
benchRot = G.bench "rot" $ G.whnf (rot (fin 7)) theAnswer
benchSum = G.bench "sum" $ G.whnf sum theAnswer
benchSumMap = G.bench "sumMap" $ G.whnf (sum . fmap (+7)) theAnswer
benchFoldr = G.bench "foldr" $ G.whnf (foldr (+) 0) theAnswer
benchFoldr1 = G.bench "foldr1" $ G.whnf (foldr1 (+)) theAnswer
benchFoldr' = G.bench "foldr'" $ G.whnf (foldr' (+) 0) theAnswer
benchFoldl = G.bench "foldl" $ G.whnf (foldl (+) 0) theAnswer
benchFoldl1 = G.bench "foldl1" $ G.whnf (foldl1 (+)) theAnswer
benchFoldl' = G.bench "foldl'" $ G.whnf (foldl' (+) 0) theAnswer
benchAppend = G.bench "append" $ G.whnf (\x -> x ++ x) theAnswer
benchAppendMap = G.bench "appendMap" $ G.whnf (\x -> x ++ fmap (+2) x) theAnswer

benchTraverseIO = G.bench "traverseIO" $
  G.whnfAppIO (traverse evaluate) theAnswer

benchLiftA2 = G.bench "liftA2" $
  G.whnf (liftA2 (+) (pure 2 :: Vec 64 Int)) theAnswer

benchConvolve = G.bench "convolve" $ G.nf
  (\x -> liftA3
    (\a b c -> a + b + c)
    (rot (fin 1) x)
    x
    (rot (modNegate (fin 1)) x))
  theAnswer

benchMapWithPos = G.bench "mapWithPos'" $
  G.whnf (imap (\i -> (+) (finToInt i))) theAnswer

benchMapToList = G.bench "mapToList" $ G.nf (map (+2) . toList) theAnswer
benchMapToListMap = G.bench "mapToListMap" $
  G.nf (map (+2) . toList . fmap (+2)) theAnswer

benchSumToListMap = G.bench "sumToListMap" $
  G.nf (sum . toList . fmap (+2)) theAnswer

benchEq_true = G.bench "eq_true" $ G.whnf (\x -> x == x) theAnswer

benchEq_false = G.bench "eq_false" $
  G.whnf (\ (x, y) -> x == y) (theAnswer, (+1) <$> theAnswer)

benchTake = G.bench "take" $ G.whnf (fst . split @50) theAnswer
benchMapTake = G.bench "mapTake" $
  G.whnf (fst . split @50 . fmap (+2)) theAnswer

benchDrop = G.bench "drop" $ G.whnf (snd . split @50) theAnswer
benchMapDrop = G.bench "mapDrop" $
  G.whnf (snd . split @50 . fmap (+2)) theAnswer

benchSplit = G.bench "split" $
  G.whnf (\x -> let (l, r) = split @50 x in l `seq` r `seq` (l, r)) theAnswer

main :: IO ()
main = G.defaultMainWith (G.defaultConfig { G.minSamples = Just 5 }) $
  [ benchForce_DeepSeq
  , benchPure
  , benchMap, benchMap2, benchMapCoerce, benchMapId
  , benchTraverseIO
  , benchLiftA2
  , benchConvolve
  , benchMapWithPos
  , benchRot
  , benchSum, benchSumMap
  , benchFoldr, benchFoldr1, benchFoldr', benchFoldl, benchFoldl1, benchFoldl'
  , benchAppend, benchAppendMap
  , benchMapToList, benchMapToListMap, benchSumToListMap
  , benchEq_true, benchEq_false
  , benchTake, benchMapTake, benchDrop, benchMapDrop
  , benchSplit
  ]