on master help sign in
Add prime sieves to benchmarks
a3c3db4Harendra Kumar
benchmark/Streamly/Benchmark/Prelude/Serial.hs+33
@@ -855,6 +855,25 @@ o_1_space_mappingX4 value =
855 ]
855 ]
856 ]
856 ]
857
857
858+{-# INLINE sieveScan #-}
859+sieveScan :: Monad m => SerialT m Int -> SerialT m Int
860+sieveScan =
861+ S.mapMaybe snd
862+ . S.scanlM' (\(primes, _) n -> do
863+ return $
864+ let ps = takeWhile (\p -> p * p <= n) primes
865+ in if P.all (\p -> n `mod` p /= 0) ps
866+ then (primes ++ [n], Just n)
867+ else (primes, Nothing)) ([2], Just 2)
868+
869+o_n_space_mapping :: Int -> [Benchmark]
870+o_n_space_mapping value =
871+ [ bgroup "mapping"
872+ [ benchIO "naive prime sieve"
873+ (\n -> S.sum $ sieveScan $ S.enumerateFromTo 2 (value + n))
874+ ]
875+ ]
876+
858-------------------------------------------------------------------------------
877-------------------------------------------------------------------------------
859-- Iteration/looping utilities
878-- Iteration/looping utilities
860-------------------------------------------------------------------------------
879-------------------------------------------------------------------------------
@@ -1657,6 +1676,17 @@ o_1_space_monad value =
1657 ]
1676 ]
1658 ]
1677 ]
1659
1678
1679+-- This is a good benchmark but inefficient way to compute primes. As we see a
1680+-- new prime we keep appending a division filter for all the future numbers.
1681+{-# INLINE sieve #-}
1682+sieve :: Monad m => SerialT m Int -> SerialT m Int
1683+sieve s = do
1684+ r <- lift $ S.uncons s
1685+ case r of
1686+ Just (prime, rest) ->
1687+ prime `S.cons` sieve (S.filter (\n -> n `mod` prime /= 0) rest)
1688+ Nothing -> S.nil
1689+
1660o_n_space_monad :: Int -> [Benchmark]
1690o_n_space_monad :: Int -> [Benchmark]
1661o_n_space_monad value =
1691o_n_space_monad value =
1662 [ bgroup "Monad"
1692 [ bgroup "Monad"
@@ -1668,6 +1698,8 @@ o_n_space_monad value =
1668 toListM value serially
1698 toListM value serially
1669 , benchIO "(>>=) (sqrt n x sqrt n) (toListSome)" $
1699 , benchIO "(>>=) (sqrt n x sqrt n) (toListSome)" $
1670 toListSome value serially
1700 toListSome value serially
1701+ , benchIO "naive prime sieve (n/4)"
1702+ (\n -> S.sum $ sieve $ S.enumerateFromTo 2 (value `div` 4 + n))
1671 ]
1703 ]
1672 ]
1704 ]
1673
1705
@@ -1823,6 +1855,7 @@ main = do
1823
1855
1824 -- transformation
1856 -- transformation
1825 , o_n_space_traversable size
1857 , o_n_space_traversable size
1858+ , o_n_space_mapping size
1826 , o_n_space_grouping size
1859 , o_n_space_grouping size
1827
1860
1828 -- multi-stream
1861 -- multi-stream