In [1]:
import Data.List (foldl')
This implementation should be ~O(2N):
In [2]:
partition :: (Ord a) => [a] -> a -> [a]
partition xs pivot =
[ x | x <- xs, x < pivot] ++ [ x | x <- xs, x >= pivot]
This implementation should be ~O(N):
In [3]:
partition' :: (Ord a) => [a] -> a -> [a]
partition' xs pivot =
let
computeState (left, right) x =
if x < pivot then
(x : left , right)
else
(left, x : right)
in
uncurry (++) $ foldl' computeState ([], []) xs
In [4]:
partition [3, 5, 8, 5, 10, 2, 1] 5
partition' [3, 5, 8, 5, 10, 2, 1] 5
In [5]:
import System.TimeIt
import System.Random
In [6]:
sampleSize = 10000000
testRandom = take sampleSize $ randoms (mkStdGen 0)
testOrdered = [1..sampleSize]
In [7]:
length . show $ testOrdered
timeIt $ print $ length . show $ partition testOrdered (sampleSize `div` 2)
timeIt $ print $ length . show $ partition' testOrdered (sampleSize `div` 2)
Observe branch prediction effects!
In [8]:
length . show $ testRandom
timeIt $ print $ length . show $ partition testRandom 0
timeIt $ print $ length . show $ partition' testRandom 0