https://github.com/nh2/haskell-ordnub
Data.List.nub is O(n²). This one is O(n log n) by requiring an Ord instance.
https://github.com/nh2/haskell-ordnub
Last synced: 3 months ago
JSON representation
Data.List.nub is O(n²). This one is O(n log n) by requiring an Ord instance.
- Host: GitHub
- URL: https://github.com/nh2/haskell-ordnub
- Owner: nh2
- License: mit
- Created: 2013-07-14T09:01:23.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2020-07-20T16:41:53.000Z (almost 5 years ago)
- Last Synced: 2025-01-13T00:26:27.233Z (5 months ago)
- Language: HTML
- Size: 1.25 MB
- Stars: 32
- Watchers: 4
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
ordnub
======`Data.List.nub` is O(n²). This one is O(n log n) by requiring an `Ord` instance.
* Also contains a benchmark (`report.html`) that shows that `ordNub` apparently is faster than `nub` in *all* cases.
* `PACKAGES_USING_NUB.txt` contains all packages which use `nub` (made with a quick grep).
It's not the most accurate since some packages define their own `nub`, but that's a minority.**This thing here is not a library.** It is a benchmark suite. [View results here](https://rawgit.com/nh2/haskell-ordnub/master/report.html).
Don't use nub
-------------If you are looking for a fast `ordNub` function to use in your code, use:
* [`nubOrd`](https://hackage.haskell.org/package/containers/docs/Data-Containers-ListUtils.html) from `containers`
([stable link](https://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Containers-ListUtils.html)) which after many years was finally added (also in response to this repo).
If you don't have a new enough `containers` or don't want to depend on it, use:
```haskell
import qualified Data.Set as SetordNub :: (Ord a) => [a] -> [a]
ordNub l = go Set.empty l
where
go _ [] = []
go s (x:xs) = if x `Set.member` s then go s xs
else x : go (Set.insert x s) xs
```### Other Data.List functions you NEVER want to use
`\\`, `union`, `intersect` - they too are *O(n²)*.
Also be aware that they don't work like sets. For example:
```
> [1,1,2] \\ [1]
[1,2]> union [1,2,3,1] [1,4]
[1,2,3,1,4]
```The current *O(n log n)* recommendation for `\\` is:
```haskell
import qualified Data.Map.Strict as MaplistDifference :: (Ord a) => [a] -> [a] -> [a]
listDifference a b = go initHist a
where
initHist = Map.fromListWith (+) [ (x, 1 :: Int) | x <- b ]go _ [] = []
go hist (x:xs) = case Map.lookup x hist of
Just n | n > 0 -> go (Map.insert x (n-1) hist) xs
_ -> x : go hist xs
```The current *O(n log n)* recommendation for `union` is:
```haskell
import qualified Data.Set as SetlistUnion :: (Ord a) => [a] -> [a] -> [a]
listUnion a b = a ++ ordNub (filter (`Set.notMember` aSet) b)
where
aSet = Set.fromList a
```The current *O(n log n)* recommendation for `intersect` is:
```haskell
import qualified Data.Set as SetlistIntersect :: (Ord a) => [a] -> [a] -> [a]
listIntersect a b = filter (`Set.member` bSet) a
where
bSet = Set.fromList b
```### More functions
The file [`ordnub.hs`](./ordnub.hs) contains more functions you may be interested in, including:
```haskell
ordNubByEq :: (Eq a, Ord b) => (a -> b) -> [a] -> [a]ordNubBy :: (Ord b) => (a -> b) -> (a -> a -> Bool) -> [a] -> [a]
```These functions have longer docs so they are not copied into this README.