Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HtmlT (ScottyM) () has crazy memory usage. #193

Closed
NerdGGuy opened this issue Mar 9, 2016 · 4 comments
Closed

HtmlT (ScottyM) () has crazy memory usage. #193

NerdGGuy opened this issue Mar 9, 2016 · 4 comments

Comments

@NerdGGuy
Copy link

NerdGGuy commented Mar 9, 2016

Hi, I'm trying to generate HTML templates that contain ScottyM. I tried to create a minimal example of the issue I'm having. I assume it's due to scotty using "Control.Monad.State.Lazy"?

{-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
import Web.Scotty
import Web.Scotty.Internal.Types
import Lucid.Base
import Lucid.Html5
import Control.Monad
import qualified Data.ByteString.Lazy as BL
import qualified Control.Monad.State.Lazy as SL
import Data.Default.Class (def)
import Data.Functor.Identity

-- compile and run: main > /dev/null
-- while watching memory usage the scotty version uses GBs of memory
-- the normal Identity version does not

main = do
  BL.putStr $ SL.evalState (runS $ renderBST myscottyhtml) def --uses GBs of memory
  BL.putStr $ runIdentity $ renderBST myhtml --doesn't use GBs of memory

myscottyhtml :: HtmlT (ScottyM) ()
myscottyhtml = replicateM_ 2 $ div_ $ do
                 replicateM_ 1000 $ div_ $ do
                   replicateM_ 10000 $ div_ "test"

myhtml :: HtmlT Identity ()
myhtml = replicateM_ 2 $ div_ $ do
           replicateM_ 1000 $ div_ $ do
             replicateM_ 10000 $ div_ "test"
@NerdGGuy
Copy link
Author

NerdGGuy commented Mar 9, 2016

I added a couple more tests including one using Control.Monad.State.Strict which also uses lots of memory. Looks like it's caused by Control.Monad.State in general.

main = do
  BL.putStr $ SL.evalState (runS $ renderBST (myhtml :: HtmlT (ScottyM) ())) def --bad
  BL.putStr $ runIdentity $ renderBST (myhtml :: HtmlT Identity ()) --good
  BL.putStr $ runIdentity $ evalHtmlT $ renderBST (myhtml :: HtmlT (HtmlT Identity) ()) --good
  BL.putStr $ S.evalState (renderBST (myhtml :: HtmlT (S.State ()) ())) () --bad

myhtml :: Monad m => HtmlT m ()
myhtml = replicateM_ 2 $ div_ $ do
           replicateM_ 1000 $ div_ $ do
             replicateM_ 10000 $ div_ "test"

@chessai
Copy link
Member

chessai commented Dec 19, 2019

i'm not a big fan of lazy StateT, so this is definitely worth looking into.

@chessai
Copy link
Member

chessai commented Dec 19, 2019

Case Allocated GCs Live Check Max MaxOS
ScottyM Lazy 20,152,346,856 19,535 300,904,624 OK 1,030,278,384 3,958,374,400
ScottyM Strict 13,109,875,112 12,287 0 OK 0 619,708,416
Identity 8,472,857,320 7,825 300,927,016 OK 300,927,016 1,516,240,896

@chessai
Copy link
Member

chessai commented Dec 19, 2019

resolved in #245

@chessai chessai closed this as completed Dec 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants