從ghc 7.4升級到ghc 7.6後,我注意到我的一些數據庫調用有40倍的放緩。爲了研究,我寫了一些簡單的測試,和我的代碼基本上是:Haskell MongoDB驅動程序可能發生死鎖
timeFetch :: Pipe -> UUID.UUID -> IO()
timeFetch pipe uuid' = do
lrResult <- access pipe master "MyDB" $ (findOne (select ["uid" =: ["$in" =: [(uuidToBUUID uuid')]]] "uidCollection") :: Action IO (Maybe Document))
case lrResult of
Right _ -> do
printCrntTm "Right has result"
timeFetch pipe uuid'
Left _ -> printCrntTm "Left err"
printCrntTm
只是顯示當前時間的描述字符串,uuidToBUUID
是因爲Data.UUID是從蒙戈的數據不同的類型。 Bson UUID類型。 timeFetch
本身遞歸地自我調用自己無限期。
所以在GHC 7.6,我看到:
2013-12-09 09:35:52.307008 UTC Right has result
2013-12-09 09:35:52.348027 UTC Right has result
2013-12-09 09:35:52.389047 UTC Right has result
2013-12-09 09:35:52.430041 UTC Right has result
2013-12-09 09:35:52.471031 UTC Right has result
2013-12-09 09:35:52.512061 UTC Right has result
2013-12-09 09:35:52.553043 UTC Right has result
但GHC 7.4,我見:
2013-12-09 09:36:38.109144 UTC Right has result
2013-12-09 09:36:38.110297 UTC Right has result
2013-12-09 09:36:38.111248 UTC Right has result
2013-12-09 09:36:38.112398 UTC Right has result
2013-12-09 09:36:38.113185 UTC Right has result
2013-12-09 09:36:38.114248 UTC Right has result
,這是相當多的1毫秒比40毫秒!我還需要提及的是,有一次爲7.6版本,我得到了:*** Exception: thread blocked indefinitely in an MVar operation
(但從來沒有),這使我想到我的主要問題。
我周圍挖一個比特,並且不知的代碼在Database.MongoDB這些線將是罪魁禍首:
newCursor :: (MonadIO m, MonadBaseControl IO m) => Database -> Collection -> BatchSize -> DelayedBatch -> Action m Cursor
--^Create new cursor. If you don't read all results then close it. Cursor will be closed automatically when all results are read from it or when eventually garbage collected.
newCursor db col batchSize dBatch = do
var <- newMVar dBatch
let cursor = Cursor (db <.> col) batchSize var
mkWeakMVar var (closeCursor cursor)
return cursor
#if !MIN_VERSION_base(4,6,0)
where mkWeakMVar = addMVarFinalizer
#endif
的base
模塊中GHC 7.6是4.6.x.x而在GHC 7.4。它是4.5.x.x.
我不是哈斯克爾的專家,也不是併發編程;有人能說明我看到的40倍慢度是可以解釋的嗎?需要調試Database.MongoDB
庫代碼嗎?提前致謝!