Commit a785da64 authored by Steffen Michels's avatar Steffen Michels

Merge branch '86-map-and-set-performance' into 'master'

Resolve "Use new compare -> {LT,EQ,GT} in Data.Map and Data.Set"

Closes #86

See merge request !316
parents 64644eef 9da037d6
Pipeline #40934 passed with stage
in 1 minute and 54 seconds
......@@ -82,6 +82,12 @@ import StdClass
* The abstract Map type provides the mapping.
* For example "Map Int String" is a mapping "from" integers "to" strings.
*
* Notes on performance:
* - For maps from `Int`, you can use Data.IntMap in many cases.
* - Avoid using tuples as keys, since strictness information is lost in their
* `<` instance. Instead, define a (local) record with strict fields where
* appropriate.
*
* @var The key type on which the data structure is indexed.
* @var The type of the values stored in the mapping.
*
......@@ -170,6 +176,7 @@ mapSize :: !(Map k v) -> Int
* @complexity O(log n)
*/
put :: !k !a !(Map k a) -> Map k a | < k
special k=Int; k=String
/**
* Searches for a value at a given key position. Works only for non-unique
......@@ -194,6 +201,7 @@ get k m :== get` k m
* Searches for a value at a given key position. Works also for unique mappings.
*/
getU :: !k !w:(Map k v) -> x:(!Maybe v, !y:(Map k v)) | == k & < k, [ x <= y, w <= y]
special k=Int; k=String
/**
* Removes the value at a given key position. The mapping itself can be spine unique.
......@@ -209,11 +217,13 @@ getU :: !k !w:(Map k v) -> x:(!Maybe v, !y:(Map k v)) | == k & < k, [ x <= y, w
* m` = del k m
*/
del :: !k !(Map k a) -> Map k a | < k
special k=Int; k=String
/**
* Removes the value at a given key position. The mapping can be unique.
*/
delU :: !a !.(Map a b) -> u:(!v:(Maybe b), !Map a b) | == a & < a, [u <= v] // !k !w:(Map k u:v) -> x:(Maybe u:v, !y:(Map k u:v)) | == k & < k, [ w y <= u, x <= y, w <= y]
special a=Int; a=String
foldrWithKey :: !(k v u:a -> u:a) !u:a !(Map k v) -> u:a
foldlWithKey :: !(.a -> .(k -> .(v -> .a))) !.a !(Map k v) -> .a
......@@ -278,6 +288,7 @@ toAscList m :== foldrWithKey (\k x xs -> [(k,x):xs]) [] m
* @complexity O(n*log n)
*/
fromList :: !u:[v:(a, b)] -> Map a b | == a & < a, [u <= v]
special a=Int; a=String
/**
* The keys of all keys of a map.
......@@ -301,6 +312,7 @@ derive gLexOrd Map
* @complexity O(log n)
*/
member :: !k !(Map k a) -> Bool | < k
special k=Int; k=String
/**
* Checks if a key is not a member of a Map.
......@@ -318,6 +330,7 @@ notMember k m :== not (member k m)
* @complexity O(log n)
*/
find :: !k !(Map k a) -> a | < k
special k=Int; k=String
/**
* Find an element in a Map.
......@@ -332,6 +345,7 @@ find :: !k !(Map k a) -> a | < k
* @complexity O(log n)
*/
findWithDefault :: !a !k !(Map k a) -> a | < k
special k=Int; k=String
/**
......@@ -359,6 +373,7 @@ findKey :: !a !(Map k a) -> Maybe k | == a
* @complexity O(n)
*/
findKeyWith :: !(a -> Bool) !(Map k a) -> Maybe k
special k=Int; k=String
/**
* Find the key of an element in a Map.
......@@ -392,12 +407,14 @@ findKeyWithDefaultWith :: !(a -> Bool) !k !(Map k a) -> k
alter :: !((Maybe a) -> Maybe a) !k !(Map k a) -> Map k a | < k
special k=Int; k=String
/**
* Get the index of a key in a Map so that it can be retrieved with
* {{`elemAt`}}.
*/
getIndex :: !k !(Map k a) -> Maybe Int | < k
special k=Int; k=String
/**
* Get the entry at a certain index. To get an index for a certain key, see
......@@ -421,23 +438,32 @@ findMin :: !(Map k a) -> (!k, !a)
findMax :: !(Map k a) -> (!k, !a)
unions :: ![Map k a] -> Map k a | < k
special k=Int; k=String
unionsWith :: !(a a -> a) ![Map k a] -> Map k a | < k
special k=Int; k=String
unionWith :: !(a a -> a) !(Map k a) !(Map k a) -> Map k a | < k
special k=Int; k=String
unionWithKey :: !(k a a -> a) !(Map k a) !(Map k a) -> Map k a | < k
special k=Int; k=String
intersection :: !(Map k a) !(Map k b) -> Map k a | < k
special k=Int; k=String
intersectionWith :: !(a b -> c) !(Map k a) !(Map k b) -> Map k c | < k
special k=Int; k=String
intersectionWithKey :: !(k a b -> c) !(Map k a) !(Map k b) -> Map k c | < k
special k=Int; k=String
union :: !(Map k a) !(Map k a) -> Map k a | < k
special k=Int; k=String
mergeWithKey :: !(k a b -> Maybe c) !((Map k a) -> Map k c) !((Map k b) -> Map k c)
!(Map k a) !(Map k b) -> Map k c | < k
special k=Int; k=String
/**
* Removes the values at given key positions. The mapping itself can be spine unique.
......@@ -464,6 +490,8 @@ where
fmap :: !(a -> b) !(Map k a) -> Map k b
difference :: !(Map k a) !(Map k b) -> Map k a | < k
special k=Int; k=String
mapWithKey :: !(k a -> b) !(Map k a) -> Map k b
isSubmapOf :: !(Map k a) !(Map k a) -> Bool | < k & Eq a
isSubmapOfBy :: !(a b -> Bool) !(Map k a) !(Map k b) -> Bool | < k
special k=Int; k=String
......@@ -76,6 +76,9 @@ from Data.Foldable import class Foldable
/**
* A `Set a` is an unordered, uncounted collection of values of type `a`.
*
* Like with keys in `Map`, avoid tuple elements since this can be slow.
* Instead, define a (local) record with strict fields where appropriate.
*
* @invariant integrity: A.s :: Set a | Eq, genShow{|*|}, gPrint{|*|} a:
* // Check that the data structure is still correct.
* name "no_duplicates" (no_duplicates s) /\
......@@ -140,6 +143,7 @@ size s :== case s of
* member x s <==> isMember x (toList s)
*/
member :: !a !(Set a) -> Bool | < a
special a=Int; a=String
/**
* Checks if an element is not in the set.
......@@ -158,6 +162,7 @@ notMember x t :== not (member x t)
isSubsetOf t1 t2 :== (size t1 <= size t2) && (isSubsetOfX t1 t2)
isSubsetOfX :: !(Set a) !(Set a) -> Bool | < a
special a=Int; a=String
/**
* Is t1 a proper subset of t2?
......@@ -197,6 +202,7 @@ singleton :: !u:a -> w:(Set u:a), [w <= u]
* integrity xs` // Data structure integrity
*/
insert :: !a !.(Set a) -> Set a | < a
special a=Int; a=String
/**
* Delete an element from a set.
......@@ -209,6 +215,7 @@ insert :: !a !.(Set a) -> Set a | < a
* integrity xs` // Data structure integrity
*/
delete :: !a !.(Set a) -> Set a | < a
special a=Int; a=String
/**
* The minimal element of a set.
......@@ -311,6 +318,7 @@ maxView :: !.(Set a) -> .(Maybe (!a, !Set a))
* elems = toList xs ++ toList ys
*/
union :: !u:(Set a) !u:(Set a) -> Set a | < a
special a=Int; a=String
/**
* The union of a list of sets.
......@@ -330,6 +338,7 @@ unions ts :== foldl union newSet ts
* (xs`,ys`) = (toList xs, toList ys)
*/
difference :: !(Set a) !(Set a) -> Set a | < a
special a=Int; a=String
/**
* The intersection of two sets.
......@@ -345,12 +354,14 @@ difference :: !(Set a) !(Set a) -> Set a | < a
* (xs`,ys`) = (toList xs, toList ys)
*/
intersection :: !(Set a) !(Set a) -> Set a | < a
special a=Int; a=String
/**
* The intersection of a list of sets.
* Elements of the result come from the first set
*/
intersections :: ![Set a] -> Set a | < a
special a=Int; a=String
/**
* Filter all elements that satisfy the predicate.
......@@ -360,6 +371,7 @@ intersections :: ![Set a] -> Set a | < a
* =.= sort (removeDup ('StdList'.filter (pred p) (toList xs)))
*/
filter :: !(a -> Bool) !(Set a) -> Set a | < a
special a=Int; a=String
/**
* Partition the set into two sets, one with all elements that satisfy the
......@@ -381,6 +393,7 @@ filter :: !(a -> Bool) !(Set a) -> Set a | < a
* xs` = true` ++ false`
*/
partition :: !(a -> Bool) !(Set a) -> (!Set a, !Set a) | < a
special a=Int; a=String
/**
* Split a set in elements less and elements greater than a certain pivot.
......@@ -404,6 +417,7 @@ partition :: !(a -> Bool) !(Set a) -> (!Set a, !Set a) | < a
* xs` = lt` ++ gt`
*/
split :: !a !(Set a) -> (!Set a, !Set a) | < a
special a=Int; a=String
/**
* Performs a 'split' but also returns whether the pivot element was found in
......@@ -425,6 +439,7 @@ split :: !a !(Set a) -> (!Set a, !Set a) | < a
* xs` = lt` ++ gt`
*/
splitMember :: !a !(Set a) -> (!Set a, !Bool, !Set a) | < a
special a=Int; a=String
/**
* Convert the set to an ascending list of elements.
......@@ -447,6 +462,7 @@ toAscList t :== 'Data.Foldable'.foldr` (\a as -> [a:as]) [] t
* @complexity O(n*log n)
*/
fromList :: ![a] -> Set a | < a
special a=Int; a=String
/**
* Map a function to all elements in a set.
......
implementation module Data.Set
import StdClass, StdMisc, StdBool, StdFunc, StdInt, StdTuple
import StdClass, StdMisc, StdBool, StdFunc, StdInt, StdString, StdTuple
import Data.Maybe, Data.GenEq, Data.GenLexOrd, Data.Monoid
from Data.Foldable import class Foldable (..)
import Data.Func
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment