基准测试如下:
#!/usr/bin/env stack
-- stack --resolver lts-16.2 script --package async --package criterion
import Control.Concurrent.Async (async, replicateConcurrently_)
import Control.Monad (replicateM_, void)
import Criterion.Main
main :: IO ()
main = defaultMain [
bgroup "tests" [ bench "sync" $ nfIO syncTest
, bench "async" $ nfIO asyncTest
]
]
syncTest :: IO ()
syncTest = replicateM_ 100000 dummy
asyncTest :: IO ()
asyncTest = replicateConcurrently_ 100000 dummy
dummy :: IO Int
dummy = return $ fib 10000000000
fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
给我这个:
% ./applicative-v-monad.hs
benchmarking tests/sync
time 2.120 ms (2.075 ms .. 2.160 ms)
0.997 R² (0.994 R² .. 0.999 R²)
mean 2.040 ms (2.023 ms .. 2.073 ms)
std dev 77.37 μs (54.96 μs .. 122.8 μs)
variance introduced by outliers: 23% (moderately inflated)
benchmarking tests/async
time 475.3 ms (310.7 ms .. 642.8 ms)
0.984 R² (0.943 R² .. 1.000 R²)
mean 527.2 ms (497.9 ms .. 570.9 ms)
std dev 41.30 ms (4.833 ms .. 52.83 ms)
variance introduced by outliers: 21% (moderately inflated)
很明显 asyncTest 运行时间比 syncTest 长。
我会认为同时运行昂贵的操作会比按顺序运行更快。我的推理有问题吗?