Tôi cố gắng để đẩy nhanh tiến độ các chức năng sau:Khả năng tăng tốc chức năng này là gì?
{-# LANGUAGE BangPatterns #-}
import Data.Word
import Data.Bits
import Data.List (foldl1')
import System.Random
import qualified Data.List as L
data Tree a = AB (Tree a) (Tree a) | A (Tree a) | B (Tree a) | C !a
deriving Show
merge :: Tree a -> Tree a -> Tree a
merge (C x) _ = C x
merge _ (C y) = C y
merge (A ta) (A tb) = A (merge ta tb)
merge (A ta) (B tb) = AB ta tb
merge (A ta) (AB tb tc) = AB (merge ta tb) tc
merge (B ta) (A tb) = AB tb ta
merge (B ta) (B tb) = B (merge ta tb)
merge (B ta) (AB tb tc) = AB tb (merge ta tc)
merge (AB ta tb) (A tc) = AB (merge ta tc) tb
merge (AB ta tb) (B tc) = AB ta (merge tb tc)
merge (AB ta tb) (AB tc td) = AB (merge ta tc) (merge tb td)
Để nhấn mạnh hiệu quả của nó, tôi đã thực hiện loại sử dụng merge
:
fold ab a b c list = go list where
go (AB a' b') = ab (go a') (go b')
go (A a') = a (go a')
go (B b') = b (go b')
go (C x) = c x
mergeAll :: [Tree a] -> Tree a
mergeAll = foldl1' merge
foldrBits :: (Word32 -> t -> t) -> t -> Word32 -> t
foldrBits cons nil word = go 32 word nil where
go 0 w !r = r
go l w !r = go (l-1) (shiftR w 1) (cons (w.&.1) r)
word32ToTree :: Word32 -> Tree Word32
word32ToTree w = foldrBits cons (C w) w where
cons 0 t = A t
cons 1 t = B t
toList = fold (++) id id (\ a -> [a])
sort = toList . mergeAll . map word32ToTree
main = do
is <- mapM (const randomIO :: a -> IO Word32) [0..500000]
print $ sum $ sort is
Việc thực hiện đã đưa ra khá tốt từ đường đi , chậm hơn khoảng 2,5x so với sort
của Data.List
. Không có gì mà tôi đã tăng tốc thêm nữa, mặc dù: nhấn mạnh một số chức năng, ghi chú bằng giọng nói ở nhiều nơi, UNPACK
trên C !a
. Có cách nào để tăng tốc độ chức năng này không?
Bạn có bao gồm chi phí 'map word32ToTree' trong chi phí' sắp xếp' không? Làm thế nào nhanh chóng là 'mergeAll' nếu bạn buộc' bản đồ word32ToTree' đầu tiên? Làm thế nào nhanh là nó nếu bạn buộc kết quả với một cái gì đó khác hơn là 'toList'? – Cirdec
Tôi không biết về tốc độ, nhưng như một vấn đề về phong cách, bạn có thể thực hiện các typeclass "Có thể gập lại" để bạn có thể gọi chức năng cơ bản mà không cần chuyển đổi thành danh sách – Bruno
@Cirdec Tôi đã không nghĩ về bất kỳ điều đó. – MaiaVictor