Switch to faster implementation of grouping a list

Why?
====

Immediately after searching the codebase after tokens, we group results
together based on match. This can be slow, especially within large
codebases. This improves the time taken, previously O(n^2).

Code reference: http://stackoverflow.com/a/15412231
Corresponding benchmark: https://gist.github.com/joshuaclayton/3dcde3b19e2c3006ee922053edebc417
This commit is contained in:
Joshua Clayton 2016-05-17 08:33:41 -04:00
parent 2e3bb0e67c
commit 4c8e8b2d72

View File

@ -2,11 +2,11 @@ module Unused.Util
( groupBy
) where
import Data.List (nub)
import Control.Arrow ((&&&))
import qualified Data.List as L
import Data.Function
groupBy :: Eq b => (a -> b) -> [a] -> [(b, [a])]
groupBy f l =
fmap (\t -> (t, byTerm t)) uniqueTerms
where
byTerm t = filter ((== t) . f) l
uniqueTerms = nub $ fmap f l
groupBy :: (Ord b) => (a -> b) -> [a] -> [(b, [a])]
groupBy f = map (f . head &&& id)
. L.groupBy ((==) `on` f)
. L.sortBy (compare `on` f)