Mapping seemingly degrades performance
See original GitHub issueI have the following definitions using 2.13.0 (somewhat pseudo-notation):
// Custom generators
// Gen<Tree<Box<'a>>>
let genTree () = TreeGenerator.tree Arb.generate<Box<'a>>
type T<'a> = T of Tree<Box<'a>>
// Gen<T<'a>>, so basically a packaged tree
let genWrappedTree () = T <!> genTree ()
// Registrations and tests
type Generators () =
static member T () = Arb.fromGen ^ genWrappedTree ()
static member Tree () = Arb.fromGen ^ genTree ()
// Takes 5 minutes to complete with huge input data
let prop1 (tree : T<int>) = predicate tree
// Takes 2 seconds to complete with good looking input data
let prop2 (tree : Tree<Box<int>>) = predicate (T tree)
Generator TreeGenerator.tree
recursively generates a rose tree (with elements generated by the given generator) taking current size into account and distributing it among the sub-trees. Box<'a>
is a record type. Generators genTree
and genWrappedTree
differ only in mapping over the box tree generator.
It would seem that mapping in genWrappedTree
considerably affects performance: prop1
is wildly slower than prop2
, where T
is applied inside the test. Besides running times, I made the following observations:
- Input generated in
prop1
is much larger than inprop2
. 300000 lines vs 7000 when using the verbose configuration. - Not registering
genWrappedTree
makesprop1
andprop2
comparable, both in terms of running time and generated input. T <!> Gen.resize 1 (genTree ())
helps, butGen.sized (fun s -> T <!> Gen.resize s (genTree ()))
does not.
I am especially puzzled by the second observation. This example is but a simple wrapper which could be applied inside a property, but my real use-case is working with another tree type, which is the result of applying a catamorphism to Tree<Box<..>>
instead of T
. So I would like to have a genWrappedTree
-like generator, but this seems out of reach for the moment.
Am I doing something wrong and is there an explanation for this performance drop and size behavior?
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
Hm, interesting. I will take a look. Thanks for the detailed writeup.
I cannot reproduce that though. So I still think you may have some issue with registration of the generators or something like that. When I run your experiment 3 in FSI,
fast()
andslow()
take about the same time.