考虑以下基准:列表为什么列表和导航不一样? (哈斯克尔)
module Main where
import qualified Data.List as L
import qualified Data.Vector.Unboxed as U
import Criterion.Main
goodSum :: Int -> Double
{-# NOINLINE goodSum #-}
goodSum n =
let ints = U.enumFromN 0 (n * n * 10) :: U.Vector Int
in U.foldl' (+) 0 $ U.map fromIntegral ints
badSum :: Int -> Double
{-# NOINLINE badSum #-}
badSum n = L.foldl' (+) 0.5 [fromIntegral i | i <- [0 .. 10*n*n]]
badSum2 :: Int -> Double
{-# NOINLINE badSum2 #-}
badSum2 n = L.foldr (+) 0.5 [fromIntegral i | i <- [0 .. 10*n*n]]
worstSum :: Int -> Double
{-# NOINLINE worstSum #-}
worstSum n = L.foldl1' (+) $ do
i <- [0 .. n*n]
return $ L.foldl1' (+) $ do
k <- [0 .. 10]
return $ fromIntegral $ k + i
main = do
defaultMain
[ bench "good" $ nf goodSum 500
, bench "bad" $ nf badSum 500
, bench "bad2" $ nf badSum2 500
, bench "worst" $ nf worstSum 500
]
结果:
benchmarking good
time 1.826 ms (1.819 ms .. 1.835 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 1.810 ms (1.803 ms .. 1.817 ms)
std dev 23.18 μs (19.91 μs .. 27.96 μs)
benchmarking bad
time 38.38 ms (38.07 ms .. 38.74 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 38.23 ms (38.07 ms .. 38.38 ms)
std dev 298.5 μs (220.6 μs .. 417.8 μs)
benchmarking bad2
time 77.87 ms (73.74 ms .. 82.67 ms)
0.992 R² (0.976 R² .. 0.998 R²)
mean 78.14 ms (75.33 ms .. 82.13 ms)
std dev 5.184 ms (3.056 ms .. 7.966 ms)
variance introduced by outliers: 19% (moderately inflated)
benchmarking worst
time 80.80 ms (79.53 ms .. 82.10 ms)
1.000 R² (0.999 R² .. 1.000 R²)
mean 80.73 ms (80.29 ms .. 81.19 ms)
std dev 756.9 μs (591.9 μs .. 938.2 μs)
列表理解为good producers and foldr
is a good consumer,那么为什么没有列出导火索?
FYI - 'Double'具有'Enum'实例,因此该'map'是不必要 - '(\ N - > enumFromTo 0 $ fromIntegral N):: INT - > [双]' – rampion 2014-12-06 04:06:16
风铃草:谢谢,但我想确保它正在进行从Int到Double的转换。 – yong 2014-12-06 04:07:32