Я тестировал производительность функции partition
для списков и получил некоторые странные результаты, я думаю.Фильтр бенчмаркинга и раздел
У нас есть то, что partition p xs == (filter p xs, filter (not . p) xs)
, но мы выбрали первую реализацию, потому что она выполняет только один обход по списку. Тем не менее, результаты, которые я получил, говорят, что, возможно, лучше использовать реализацию, которая использует два обхода.
Вот минимальный код, который показывает, что я вижу
import Criterion.Main
import System.Random
import Data.List (partition)
mypartition :: (a -> Bool) -> [a] -> ([a],[a])
mypartition p l = (filter p l, filter (not . p) l)
randList :: RandomGen g => g -> Integer -> [Integer]
randList gen 0 = []
randList gen n = x:xs
where
(x, gen') = random gen
xs = randList gen' (n - 1)
main = do
gen <- getStdGen
let arg10000000 = randList gen 10000000
defaultMain [
bgroup "filters -- split list in half " [
bench "partition100" $ nf (partition (>= 50)) arg10000000
, bench "mypartition100" $ nf (mypartition (>= 50)) arg10000000
]
]
Я побежал тесты как с -O
и без него, и оба раза я получаю, что двойные обходы лучше.
Я использую ghc-7.10.3
с criterion-1.1.1.0
Мои вопросы:
Является ли это ожидалось?
Правильно ли я использую Критерий? Я знаю, что лень может быть сложным, и
(filter p xs, filter (not . p) xs)
будет выполнять только два обхода, если используются оба элемента кортежа.Должно ли это что-то сделать, поскольку списки обрабатываются в Haskell?
Большое спасибо!
Вы используете «критерий» довольно правильно, но в идеале вы должны использовать 'env', чтобы создать рандомизированный список и передать его в контрольные точки, или, по крайней мере, обязательно закрепите этот список до начала бенчмаркинга. – dfeuer
Кроме того, поскольку это вопрос о производительности, вы должны сообщить нам, какую версию GHC вы используете. – dfeuer
Спасибо. Я редактировал свой вопрос. Я использую 'ghc-7.10.3'. Знаете ли вы, есть ли причина, по которой в этом случае ускоряются два обхода? Я тестировал это также, используя локальную реализацию списков, поскольку я думал, что это может быть связано с реализацией ghc, но результаты не меняются! – aesadde