New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce Benchmarks #43
Changes from 4 commits
85cb10a
d2de104
cdc79fc
89e6071
c3970b0
13ef0cc
5b25dd9
284b650
9ff9933
1d07081
cd097b7
14630a2
1f4bc9c
cda3eab
335158b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,39 @@ | ||||||
{-# LANGUAGE BangPatterns #-} | ||||||
{-# LANGUAGE ScopedTypeVariables #-} | ||||||
{-# LANGUAGE NoImplicitPrelude #-} | ||||||
{-# LANGUAGE TypeFamilies #-} | ||||||
{-# LANGUAGE OverloadedStrings #-} | ||||||
{-# LANGUAGE FlexibleContexts #-} | ||||||
{-# LANGUAGE TypeApplications #-} | ||||||
|
||||||
module Map.Contrib.Bench where | ||||||
|
||||||
import Map | ||||||
import Gauge.Main (Benchmark, bench, defaultMain, whnf) | ||||||
import Relude hiding (fromList, Map) | ||||||
|
||||||
benchmark | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's rename this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about this function as if it runs "all" the benchmarks a module will have. In this case, we only have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yigitozkavci Hmm, if this is the function that runs all benchmarks than okay |
||||||
:: forall k. (Enum k, Bounded k, Key k, NFData (Map k Int)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of requiring containers-backpack/containers-sig-readonly/src/Map.hsig Lines 29 to 30 in c84b22f
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I see the problem now. The fact that |
||||||
=> String | ||||||
-> Proxy k | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of passing benchmark "some label" (Proxy @T) you can call this function just as: benchmark @T "some label"
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I chose not to enable the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Despite the name, |
||||||
-> IO () | ||||||
benchmark label _ = do | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that |
||||||
let benchMaxElems = min 1024 (fromEnum (maxBound @k)) | ||||||
let upBound = foldl' (.) id (replicate benchMaxElems succ) minBound | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can simplify benchmarks a lot if you pass lower and upper bounds to this function. So then in let lookupRangeLower = 0
let lookupRangeUpper = 1024 and pass them to this function. So the approach is more flexible because we can easily change the range and test with other range. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm great, this is the kinda-same thing we've done with the type alias |
||||||
let map_keys :: [k] = [minBound..upBound] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The complexity here exists because I wanted to be able to write benchmarks for any There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extra complexity is okay if it allows to have polymoprhic implementation. I see lookup benchmarks from the So I think that you're doing great job here 👍 |
||||||
|
||||||
let mapEntries = zip map_keys [0..] | ||||||
|
||||||
let m = fromList mapEntries | ||||||
|
||||||
evaluateNF_ m | ||||||
|
||||||
defaultMain | ||||||
[ lookupBench (label <> "-lookup/all") m (map fst mapEntries) | ||||||
] | ||||||
|
||||||
lookupBench :: forall k. Key k => String -> Map k Int -> [k] -> Benchmark | ||||||
lookupBench label m = bench label . whnf (go 0) | ||||||
where | ||||||
go :: Int -> [k] -> Int | ||||||
go = foldl' (\a -> (a +) . fromMaybe 0 . flip lookup m) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,10 +34,10 @@ module Map.Int | |
, alter | ||
) where | ||
|
||
import Prelude hiding (lookup, null) | ||
import Control.DeepSeq (NFData (..)) | ||
import Data.Coerce (coerce) | ||
|
||
import qualified Data.IntMap.Strict as M | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to our style guide, |
||
import Prelude hiding (lookup, null) | ||
|
||
newtype Map k v = IM (M.IntMap v) | ||
deriving newtype (Show, Eq) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of writing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, never used DerivingStrategies before, beautiful! |
||
|
@@ -111,3 +111,6 @@ delete = coerce @(k -> M.IntMap v -> M.IntMap v) M.delete | |
alter :: forall k v. Key k => (Maybe v -> Maybe v) -> k -> Map k v -> Map k v | ||
alter = coerce @((Maybe v -> Maybe v) -> k -> M.IntMap v -> M.IntMap v) M.alter | ||
{-# INLINE alter #-} | ||
|
||
instance NFData v => NFData (Map k v) where | ||
rnf (IM m) = rnf m |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -23,7 +23,7 @@ library | |||||||||
exposed-modules: Map.Prim | ||||||||||
reexported-modules: Map.Prim as Map | ||||||||||
|
||||||||||
build-depends: base, primitive-containers >= 0.3.0 | ||||||||||
build-depends: base, primitive-containers >= 0.3.0, deepseq | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did not know about cabal 2.0's caret operator, great, I applied the diff :) |
||||||||||
ghc-options: -Wall -fhide-source-paths | ||||||||||
-fexpose-all-unfoldings | ||||||||||
default-language: Haskell2010 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,8 @@ module Map.Prim | |
, elems | ||
) where | ||
|
||
import Control.DeepSeq (NFData (..)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that this import is not used here. Probably it's not needed. As well as |
||
|
||
import Prelude hiding (lookup, null) | ||
|
||
import Data.Maybe (fromMaybe, isJust) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Change log | ||
========== | ||
|
||
`containers-benchmark` uses [PVP Versioning][1]. | ||
The change log is available [on GitHub][2]. | ||
|
||
0.0.0 | ||
===== | ||
* Initially created. | ||
|
||
[1]: https://pvp.haskell.org | ||
[2]: https://github.com/kowainik/containers-backpack/releases | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you, please, explicit export list to this module so it will become more clear what are the internals and what is the exposed interface?