switch to the strict state monad
I had not realized what a memory leak the lazy state monad could be, although I have not seen much evidence of actual leaking in git-annex. However, if running git-annex on a great many files, this could matter. The additional Utility.State.changeState adds even more strictness, avoiding a problem I saw in github-backup where repeatedly modifying state built up a huge pile of thunks.
This commit is contained in:
parent
0609e10239
commit
a964012fc3
5 changed files with 30 additions and 16 deletions
26
Utility/State.hs
Normal file
26
Utility/State.hs
Normal file
|
@ -0,0 +1,26 @@
|
|||
{- state monad support
|
||||
-
|
||||
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
module Utility.State where
|
||||
|
||||
import Control.Monad.State.Strict
|
||||
|
||||
{- Modifies Control.Monad.State's state, forcing a strict update.
|
||||
- This avoids building thunks in the state and leaking.
|
||||
- Why it's not the default, I don't know.
|
||||
-
|
||||
- Example: changeState $ \s -> s { foo = bar }
|
||||
-}
|
||||
changeState :: MonadState s m => (s -> s) -> m ()
|
||||
changeState f = do
|
||||
x <- get
|
||||
put $! f x
|
||||
|
||||
{- Gets a value from the internal state, selected by the passed value
|
||||
- constructor. -}
|
||||
getState :: MonadState s m => (s -> a) -> m a
|
||||
getState = gets
|
Loading…
Add table
Add a link
Reference in a new issue