Skip to content

Commit 68aed6e

Browse files
committed
Improve performance of uniformSubSet and reduce duplication
1 parent b78582c commit 68aed6e

File tree

2 files changed

+16
-16
lines changed
  • libs
    • cardano-ledger-core/testlib/Test/Cardano/Ledger/Core
    • cardano-ledger-test/src/Test/Cardano/Ledger/Constrained

2 files changed

+16
-16
lines changed

libs/cardano-ledger-core/testlib/Test/Cardano/Ledger/Core/Arbitrary.hs

+14-3
Original file line numberDiff line numberDiff line change
@@ -629,13 +629,24 @@ uniformSubSet mSubSetSize inputSet gen = do
629629
subSetSize <- case mSubSetSize of
630630
Nothing -> uniformRM (0, Set.size inputSet) gen
631631
Just n -> pure $ max 0 $ min (Set.size inputSet) n
632-
go inputSet Set.empty subSetSize
632+
if subSetSize < Set.size inputSet `div` 2
633+
then
634+
goAdd inputSet Set.empty subSetSize
635+
else
636+
goDelete inputSet (Set.size inputSet - subSetSize)
633637
where
634-
go !s !acc !i
638+
-- Constructing a new Set is faster when less then a half of original Set will be used
639+
goAdd !s !acc !i
635640
| i <= 0 = pure acc
636641
| otherwise = do
637642
ix <- uniformRM (0, Set.size s - 1) gen
638-
go (Set.deleteAt ix s) (Set.insert (Set.elemAt ix s) acc) (i - 1)
643+
goAdd (Set.deleteAt ix s) (Set.insert (Set.elemAt ix s) acc) (i - 1)
644+
-- Deleting is faster when more items need to be retained in the Set
645+
goDelete !acc !i
646+
| i <= 0 = pure acc
647+
| otherwise = do
648+
ix <- uniformRM (0, Set.size acc - 1) gen
649+
goDelete (Set.deleteAt ix acc) (i - 1)
639650

640651
uniformSubMap ::
641652
(StatefulGen g m, Ord k) =>

libs/cardano-ledger-test/src/Test/Cardano/Ledger/Constrained/Combinators.hs

+2-13
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Data.Set (Set)
1414
import qualified Data.Set as Set
1515
import GHC.Stack (HasCallStack)
1616
import Test.Cardano.Ledger.Binary.Random (QC (..))
17-
import Test.Cardano.Ledger.Core.Arbitrary (uniformSubMap)
17+
import Test.Cardano.Ledger.Core.Arbitrary (uniformSubMap, uniformSubSet)
1818
import Test.QuickCheck hiding (Fixed, total)
1919

2020
-- ==========================================================================
@@ -122,18 +122,7 @@ subsetFromSetWithSize mess set n
122122
++ show (Set.size set)
123123
)
124124
mess
125-
-- It is faster to remove extra elements, when we need to drop more than a half
126-
| Set.size set `div` 2 < n = fst <$> help (flip const) set Set.empty (Set.size set - n)
127-
-- It is faster to pick out random elements when we only need under a half of the original set.
128-
| otherwise = snd <$> help seq set Set.empty n
129-
where
130-
help optSeq !source target count
131-
| count <= 0 = pure (source, target)
132-
| otherwise = do
133-
(item, source') <- itemFromSet (("subsetFromSetWithSize " ++ show n) : mess) source
134-
-- To avoid a memory leak we only force the target when it is the set we want to keep.
135-
let target' = Set.insert item target
136-
target' `optSeq` help optSeq source' target' (count - 1)
125+
| otherwise = uniformSubSet (Just n) set QC
137126

138127
-- | Generate a larger map, from a smaller map 'subset'. The new larger map, should have all the
139128
-- keys and values of the smaller map.

0 commit comments

Comments
 (0)