Haskell 具有 Bang 模式的严格 MVar
Haskell Strict MVar with Bang pattern
执行以下代码示例大约需要 2 秒。但是,当删除第 14 行中的 bang 模式时,需要 60 秒。谁能解释一下这是怎么回事?
我使用的是严格的 MVar,因此无论放入 MVar 中什么,都应该完全评估为正常形式。在插入 MVar 之前,我不希望 Bang 模式产生任何明显的效果。
{-# LANGUAGE BangPatterns #-}
import Control.Concurrent.MVar.Strict
import qualified Data.Text as T
import Data.Text.Encoding
main :: IO ()
main = do
mvar <- newMVar T.empty
let bsArr = map (\i -> encodeUtf8 $ T.pack $ "some strange string " ++ show i) [0 .. 30000 :: Int]
mvarWriter =
\lbs ->
let !decoded = decodeUtf8 lbs
in modifyMVar_ mvar (\oldText -> return $ oldText <> decoded)
mapM_ (\lbs -> mvarWriter lbs) bsArr
print . T.length =<< readMVar mvar
您的代码大致相当于:
let !decoded = decodeUtf8 lbs
oldText <- takeMVar mvar
let !newText = oldText <> decoded
putMVar mvar newText
没有刘海图案是这样的:
oldText <- takeMVar mvar
let !newText = oldText <> decodeUtf8 lbs
putMVar mvar newText
没有 bang 模式,计算发生在可能的最新点。那是在插入新值之前。然而,此时 MVar
是空的:oldText
已经被取出。在此期间,没有其他线程可以计算任何东西。所以这意味着在任何给定时间只有一个线程可以进行实际计算。
bang 模式强制 decodeUtf8 lbs
在 MVar
被采用之前进行评估。因此,这部分计算可以与其他线程并行进行。只有相对便宜的 oldText <> decoded
计算需要发生在临界区。
执行以下代码示例大约需要 2 秒。但是,当删除第 14 行中的 bang 模式时,需要 60 秒。谁能解释一下这是怎么回事?
我使用的是严格的 MVar,因此无论放入 MVar 中什么,都应该完全评估为正常形式。在插入 MVar 之前,我不希望 Bang 模式产生任何明显的效果。
{-# LANGUAGE BangPatterns #-}
import Control.Concurrent.MVar.Strict
import qualified Data.Text as T
import Data.Text.Encoding
main :: IO ()
main = do
mvar <- newMVar T.empty
let bsArr = map (\i -> encodeUtf8 $ T.pack $ "some strange string " ++ show i) [0 .. 30000 :: Int]
mvarWriter =
\lbs ->
let !decoded = decodeUtf8 lbs
in modifyMVar_ mvar (\oldText -> return $ oldText <> decoded)
mapM_ (\lbs -> mvarWriter lbs) bsArr
print . T.length =<< readMVar mvar
您的代码大致相当于:
let !decoded = decodeUtf8 lbs
oldText <- takeMVar mvar
let !newText = oldText <> decoded
putMVar mvar newText
没有刘海图案是这样的:
oldText <- takeMVar mvar
let !newText = oldText <> decodeUtf8 lbs
putMVar mvar newText
没有 bang 模式,计算发生在可能的最新点。那是在插入新值之前。然而,此时 MVar
是空的:oldText
已经被取出。在此期间,没有其他线程可以计算任何东西。所以这意味着在任何给定时间只有一个线程可以进行实际计算。
bang 模式强制 decodeUtf8 lbs
在 MVar
被采用之前进行评估。因此,这部分计算可以与其他线程并行进行。只有相对便宜的 oldText <> decoded
计算需要发生在临界区。