diff --git a/apply-merge.cabal b/apply-merge.cabal index b2b0e6e..db37361 100644 --- a/apply-merge.cabal +++ b/apply-merge.cabal @@ -26,6 +26,7 @@ extra-doc-files: README.md ChangeLog.md docs/ALGORITHM.md + docs/Benchmark.md LICENSES/BSD-3-Clause.txt source-repository head diff --git a/docs/Benchmark.md b/docs/Benchmark.md new file mode 100644 index 0000000..e9b9113 --- /dev/null +++ b/docs/Benchmark.md @@ -0,0 +1,202 @@ +We benchmark the performance of the `applyMerge` implementations on different +"shapes" of generated elements. + +* Linear: `applyMerge const [1..] [1..]` +
+ Shape + + . . . . . . . . . . . . . . . + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ +* Triangular `applyMerge (+) [1..] [1..]` +
+ Shape + + . . . . . . . . . . . . . . * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . * * * + . . . . . . . . . . . * * * * + . . . . . . . . . . * * * * * + . . . . . . . . . * * * * * * + . . . . . . . . * * * * * * * + . . . . . . . * * * * * * * * + . . . . . . . * * * * * * * * + . . . . . . * * * * * * * * * + . . . . . * * * * * * * * * * + . . . . * * * * * * * * * * * + . . . * * * * * * * * * * * * + . . * * * * * * * * * * * * * + . * * * * * * * * * * * * * * +
+ +* Skewed triangular `applyMerge (\x y -> 4 * x + y) [1..] [1..]` +
+ Shape + + . . . . . . . . . . . . . . * + . . . . . . . . . . * * * * * + . . . . . . * * * * * * * * * + . . * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ +* Hyperbolic: `applyMerge (*) [1..] [1..]` +
+ Shape + + . . . . . . . . . . . . . . . + . . . . . . . * * * * * * * * + . . . . . * * * * * * * * * * + . . . * * * * * * * * * * * * + . . . * * * * * * * * * * * * + . . * * * * * * * * * * * * * + . . * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + +
+ +* Skewed hyperbolic `applyMerge (\x y -> x^3 * y) [1..]` +
+ Shape + + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . . . . * * * * * * + . . . * * * * * * * * * * * * + . . * * * * * * * * * * * * * + . * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ +* Circular: `applyMerge (\x y -> x*x + y*y) [1..]` +
+ Shape + + . . . . . . . . . . . . . * * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . * * * + . . . . . . . . . . . . * * * + . . . . . . . . . . . * * * * + . . . . . . . . . . . * * * * + . . . . . . . . . . * * * * * + . . . . . . . . . * * * * * * + . . . . . . . . * * * * * * * + . . . . . . * * * * * * * * * + . . . . * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ +* Elliptical: `applyMerge (\x y -> 4*x*x + y*y) [1..]` +
+ Shape + + . . . . . . . . . . . . . . * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . . * * + . . . . . . . . . . . . * * * + . . . . . . . . . . * * * * * + . . . . . . . * * * * * * * * + . . . * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ +* Composites: + + We can generate prime numbers using the Sieve of Erastosthenes: + ````haskell + primes :: [Int] + primes = 2 : ([3..] `minus` composites) -- `minus` from data-ordlist + + composites :: [Int] + composites = applyMerge (\p i -> p * (p + i)) primes [0..] + ```` + + The shape of `composites` then looks like: +
+ Shape + + . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . + . . . . . . . . . . . * * * * + . . . . * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * +
+ + Since the *n*th prime number is approximately *n* log *n*, this is a + quasi-hyperbolic shape, roughly equivalent to + + ```haskell + f :: Int -> Int -> Double + f x y = + let x' :: Double + x' = fromIntegral x + + y' :: Double + y' = fromIntegral y + + xlogx :: Double + xlogx = x' * log x' + in xlogx * (xlogx + y') + + compositesApprox :: [Double] + compositesApprox = applyMerge f [1..] [1..] + ``` diff --git a/package.yaml b/package.yaml index d761ef7..a3148fe 100644 --- a/package.yaml +++ b/package.yaml @@ -23,6 +23,7 @@ extra-doc-files: - README.md - ChangeLog.md - docs/ALGORITHM.md +- docs/Benchmark.md - LICENSES/BSD-3-Clause.txt language: GHC2021