Commits (6)
...@@ -512,9 +512,11 @@ null _ = False ...@@ -512,9 +512,11 @@ null _ = False
-- > size (singleton 1 'a') == 1 -- > size (singleton 1 'a') == 1
-- > size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3 -- > size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
size :: IntMap a -> Int size :: IntMap a -> Int
size (Bin _ _ l r) = size l + size r size = go 0
size (Tip _ _) = 1 where
size Nil = 0 go !acc (Bin _ _ l r) = go (go acc l) r
go acc (Tip _ _) = 1 + acc
go acc Nil = acc
-- | /O(min(n,W))/. Is the key a member of the map? -- | /O(min(n,W))/. Is the key a member of the map?
-- --
......
...@@ -311,9 +311,11 @@ null _ = False ...@@ -311,9 +311,11 @@ null _ = False
-- | /O(n)/. Cardinality of the set. -- | /O(n)/. Cardinality of the set.
size :: IntSet -> Int size :: IntSet -> Int
size (Bin _ _ l r) = size l + size r size = go 0
size (Tip _ bm) = bitcount 0 bm where
size Nil = 0 go !acc (Bin _ _ l r) = go (go acc l) r
go acc (Tip _ bm) = acc + bitcount 0 bm
go acc Nil = acc
-- | /O(min(n,W))/. Is the value a member of the set? -- | /O(min(n,W))/. Is the value a member of the set?
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
* Optimize `Data.IntMap.restrictKeys` and `Data.IntMap.withoutKeys`. The * Optimize `Data.IntMap.restrictKeys` and `Data.IntMap.withoutKeys`. The
semantic fix in 0.5.10.1 left them rather slow in certain cases. semantic fix in 0.5.10.1 left them rather slow in certain cases.
* Speed up `size` for `IntSet` and `IntMap` (thanks, Mike Ledger!).
* Define a custom `liftA2` in `Applicative` instances for base 4.10, and use * Define a custom `liftA2` in `Applicative` instances for base 4.10, and use
`liftA2` rather than `<*>` whenever it may be beneficial. `liftA2` rather than `<*>` whenever it may be beneficial.
......
...@@ -142,6 +142,7 @@ main = defaultMain ...@@ -142,6 +142,7 @@ main = defaultMain
, testProperty "alter" prop_alter , testProperty "alter" prop_alter
, testProperty "index" prop_index , testProperty "index" prop_index
, testProperty "null" prop_null , testProperty "null" prop_null
, testProperty "size" prop_size
, testProperty "member" prop_member , testProperty "member" prop_member
, testProperty "notmember" prop_notmember , testProperty "notmember" prop_notmember
, testProperty "lookup" prop_lookup , testProperty "lookup" prop_lookup
...@@ -906,6 +907,11 @@ prop_index xs = length xs > 0 ==> ...@@ -906,6 +907,11 @@ prop_index xs = length xs > 0 ==>
prop_null :: IMap -> Bool prop_null :: IMap -> Bool
prop_null m = null m == (size m == 0) prop_null m = null m == (size m == 0)
prop_size :: UMap -> Property
prop_size im = sz === foldl' (\i _ -> i + 1) (0 :: Int) im .&&.
sz === List.length (toList im)
where sz = size im
prop_member :: [Int] -> Int -> Bool prop_member :: [Int] -> Int -> Bool
prop_member xs n = prop_member xs n =
let m = fromList (zip xs xs) let m = fromList (zip xs xs)
......
...@@ -261,8 +261,10 @@ prop_isSubsetOf a b = isSubsetOf a b == Set.isSubsetOf (toSet a) (toSet b) ...@@ -261,8 +261,10 @@ prop_isSubsetOf a b = isSubsetOf a b == Set.isSubsetOf (toSet a) (toSet b)
prop_isSubsetOf2 :: IntSet -> IntSet -> Bool prop_isSubsetOf2 :: IntSet -> IntSet -> Bool
prop_isSubsetOf2 a b = isSubsetOf a (union a b) prop_isSubsetOf2 a b = isSubsetOf a (union a b)
prop_size :: IntSet -> Bool prop_size :: IntSet -> Property
prop_size s = size s == List.length (toList s) prop_size s = sz === foldl' (\i _ -> i + 1) (0 :: Int) s .&&.
sz === List.length (toList s)
where sz = size s
prop_findMax :: IntSet -> Property prop_findMax :: IntSet -> Property
prop_findMax s = not (null s) ==> findMax s == maximum (toList s) prop_findMax s = not (null s) ==> findMax s == maximum (toList s)
......