<div>makeSessionBackend calls "getKey" from clientsession:</div><div><br></div><a href="http://hackage.haskell.org/packages/archive/clientsession/0.8.0/doc/html/src/Web-ClientSession.html#getKey">http://hackage.haskell.org/packages/archive/clientsession/0.8.0/doc/html/src/Web-ClientSession.html#getKey</a><br>
<br>Looking at that function no wonder it is a bottleneck:<div><br></div><div><pre><span class="hs-comment" style="color:green">-- | Get a key from the given text file.</span>
<a name="line-146"></a><span class="hs-comment" style="color:green">--</span>
<a name="line-147"></a><span class="hs-comment" style="color:green">-- If the file does not exist or is corrupted a random key will</span>
<a name="line-148"></a><span class="hs-comment" style="color:green">-- be generated and stored in that file.</span>
<a name="line-149"></a><span class="hs-definition">getKey</span> <span class="hs-keyglyph" style="color:red">::</span> <span class="hs-conid">FilePath</span> <span class="hs-comment" style="color:green">-- ^ File name where key is stored.</span>
<a name="line-150"></a> <span class="hs-keyglyph" style="color:red">-></span> <span class="hs-conid">IO</span> <span class="hs-conid">Key</span> <span class="hs-comment" style="color:green">-- ^ The actual key.</span>
<a name="line-151"></a><span class="hs-definition">getKey</span> <span class="hs-varid">keyFile</span> <span class="hs-keyglyph" style="color:red">=</span> <span class="hs-keyword" style="color:blue">do</span>
<a name="line-152"></a> <span class="hs-varid">exists</span> <span class="hs-keyglyph" style="color:red"><-</span> <span class="hs-varid">doesFileExist</span> <span class="hs-varid">keyFile</span>
<a name="line-153"></a> <span class="hs-keyword" style="color:blue">if</span> <span class="hs-varid">exists</span>
<a name="line-154"></a> <span class="hs-keyword" style="color:blue">then</span> <span class="hs-conid">S</span><span class="hs-varop">.</span><span class="hs-varid">readFile</span> <span class="hs-varid">keyFile</span> <span class="hs-varop">>>=</span> <span class="hs-varid">either</span> <span class="hs-layout" style="color:red">(</span><span class="hs-varid">const</span> <span class="hs-varid">newKey</span><span class="hs-layout" style="color:red">)</span> <span class="hs-varid">return</span> <span class="hs-varop">.</span> <span class="hs-varid">initKey</span>
<a name="line-155"></a> <span class="hs-keyword" style="color:blue">else</span> <span class="hs-varid">newKey</span>
<a name="line-156"></a> <span class="hs-keyword" style="color:blue">where</span>
<a name="line-157"></a> <span class="hs-varid">newKey</span> <span class="hs-keyglyph" style="color:red">=</span> <span class="hs-keyword" style="color:blue">do</span>
<a name="line-158"></a> <span class="hs-layout" style="color:red">(</span><span class="hs-varid">bs</span><span class="hs-layout" style="color:red">,</span> <span class="hs-varid">key'</span><span class="hs-layout" style="color:red">)</span> <span class="hs-keyglyph" style="color:red"><-</span> <span class="hs-varid">randomKey</span>
<a name="line-159"></a> <span class="hs-conid">S</span><span class="hs-varop">.</span><span class="hs-varid">writeFile</span> <span class="hs-varid">keyFile</span> <span class="hs-varid">bs</span>
<a name="line-160"></a> <span class="hs-varid">return</span> <span class="hs-varid">key'</span></pre><div><br></div><div>Plenty of syscalls, reading and parsing the same file over and over again. Perhaps the default should be to store the key within the foundation datatype at startup?</div>
<div><br></div><div>Best regards,</div><div>Krzysztof Skrzętnicki</div><br><div class="gmail_quote">On Sat, Sep 1, 2012 at 10:37 AM, Lorenzo Bolla <span dir="ltr"><<a href="mailto:lbolla@gmail.com" target="_blank">lbolla@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Fri, Aug 31, 2012 at 10:13:20PM -0300, Felipe Almeida Lessa wrote:<br>
> [Forwarding to Yesod's mailing list as well. I'll copy all of the<br>
> original text below for those who aren't on haskell-beginners.]<br>
><br>
> On Fri, Aug 31, 2012 at 11:24 AM, Lorenzo Bolla <<a href="mailto:lbolla@gmail.com">lbolla@gmail.com</a>> wrote:<br>
> > Hi all,<br>
> ><br>
> > This is a question specific to the Yesod framework, but simple enough<br>
> > (I hope) to be considered a beginner question...<br>
> ><br>
> > I am puzzled by the performance of these two very simple web-servers,<br>
> > one written in Warp and another written in Yesod:<br>
> ><br>
> > === YESOD ===<br>
> ><br>
> > {-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses,<br>
> > TemplateHaskell #-}<br>
> > import Yesod<br>
> ><br>
> > data HelloWorld = HelloWorld<br>
> ><br>
> > mkYesod "HelloWorld" [parseRoutes|<br>
> > / HomeR GET<br>
> > |]<br>
> ><br>
> > instance Yesod HelloWorld<br>
> ><br>
> > getHomeR :: Handler RepHtml<br>
> > getHomeR = defaultLayout [whamlet|$newline always<br>
> > Hello World!<br>
> > |]<br>
> ><br>
> > main :: IO ()<br>
> > -- main = warpDebug 3000 HelloWorld<br>
> > main = warp 3000 HelloWorld<br>
> ><br>
> > === WARP ===<br>
> ><br>
> > {-# LANGUAGE OverloadedStrings #-}<br>
> ><br>
> > import Network.Wai<br>
> > import Network.HTTP.Types<br>
> > import Network.Wai.Handler.Warp (run)<br>
> > import Data.ByteString.Lazy.Char8 ()<br>
> ><br>
> > app :: Application<br>
> > app _ = return $ responseLBS<br>
> > status200<br>
> > [("Content-Type", "text/html")]<br>
> > "Hello, Warp!"<br>
> ><br>
> > main :: IO ()<br>
> > main = do<br>
> > putStrLn "<a href="http://localhost:8080/" target="_blank">http://localhost:8080/</a>"<br>
> > run 8080 app<br>
> ><br>
> > ===<br>
> ><br>
> > I've tested both using httperf:<br>
> > $> httperf --hog --client=0/1 --server=localhost --port=3000 --uri=/<br>
> > --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=100<br>
> > --num-calls=100 --burst-length=20<br>
> ><br>
> > and I got very different results:<br>
> ><br>
> > YESOD: Request rate: 4048.0 req/s (0.2 ms/req)<br>
> > WARP: Request rate: 33656.2 req/s (0.0 ms/req)<br>
> ><br>
> > Now, I understand that Yesod is expected to be slower than the "raw"<br>
> > Warp, but I wasn't expecting a 10x slowdown, especially for such a<br>
> > trivial Yesod app (no db, no auth, etc.).<br>
> ><br>
> > [<br>
> > Compilation command was: ghc -Wall -O2 --make yesod.hs<br>
> > $ yesod version<br>
> > yesod-core version:1.1.0<br>
> > ]<br>
> ><br>
> > What is going on?<br>
> ><br>
> > Thanks,<br>
> > L.<br>
><br>
> This is actually a rather tricky and interesting question =).<br>
><br>
> My knee-jerk reaction is "profile!". Profiling will give you more<br>
> clues about where the time is being spent.<br>
><br>
> As Bryce said, you're using defaultLayout and Hamlet, which should<br>
> slow things down. Also, you're implicitly using clientsession, you<br>
> may try setting makeSessionBackend [1] to 'const $ return Nothing' and<br>
> see what kind of performance you get.<br>
><br>
> Cheers!<br>
><br>
> [1] <a href="http://hackage.haskell.org/packages/archive/yesod-core/1.1.1.1/doc/html/Yesod-Core.html#v:makeSessionBackend" target="_blank">http://hackage.haskell.org/packages/archive/yesod-core/1.1.1.1/doc/html/Yesod-Core.html#v:makeSessionBackend</a><br>
><br>
> --<br>
> Felipe.<br>
<br>
</div></div>Good catch Felipe!<br>
It looks like `makeSessionBackend` is horribly slow... These are the numbers on<br>
my box:<br>
<br>
Warp<br>
10250 req/s<br>
<br>
Yesod<br>
hamlet: 848 req/s<br>
no-hamlet: 940 req/s (getHomeR = return ∘ RepPlain ∘ toContent $ "Hello World!")<br>
no-session: 8000 req/s (makeSessionBackend = const $ return Nothing)<br>
<span class="HOEnZb"><font color="#888888"><br>
L.<br>
<br>
--<br>
Lorenzo Bolla<br>
<a href="http://lbolla.info" target="_blank">http://lbolla.info</a><br>
</font></span><div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div>