On Fri, Apr 15, 2011 at 3:34 AM, Aur Saraf <sonoflilit@gmail.com> wrote:
First, the nice people at #haskell (specifically it was <sm>, but
there were many other helpful people there like <ksf> and others whose
names I won't remember) made me swtich from fastcgi to warp. I didn't
think it would be relevant, since my performance problems were all
memory-consumption-related, but it turned out to speed my code by
orders of magnitude. Everybody switch to warp! :-)

Intriguing. I'm writing the 0.8 migration guide now, and I'm putting in a comment about moving to Warp.
 
Second, I've been thinking about the performance bounds of a Yesod
app. As in, given an app that has no leaks etc', where can I expect it
to perform better than imperative languages I'm familiar with, where
can I expect it to perform worse?

The biggest limits imposed by Yesod that I thought about were:

* [Char] - not in Yesod 0.8
* Persistent always takes a full row - shouldn't matter much in
practice, especially if persistent is lazy and doesn't parse columns I
don't care about

Actually, Persistent is *not* lazy in this regard. The idea is to avoid any kind of errors in pure code: if you get a record from Persistent, you know that it's valid. As I've said in the past: if anyone is really suffering badly from this aspect of Persistent, they can always drop down to raw SQL for the queries in question.
 
* No joins in DB - being solved as we speak
* All page must be generated before it is sent if we plan to use Widgets --

Well, that's not *exactly* the case. Yesod does not provide an easy way to interleave IO with page responses. The reason for this is that interleaving IO introduces the possibility of errors, and once a page response has begun it will be impossible to change the HTTP status code. That's not to say that we *shouldn't* provide such a mechanism, just that there's a good reason not to provide it as the default.

I'm open to ideas for this, but my guess is that this will need to wait until post-1.0.
 
 Well, this one is interesting. It seems to be very much against
Haskell nature, that is so lazy and nice, and I think in my code it
might actually make performance difference. So I thought -- isn't it
possible to extend Hamlet to work in an Iteratee too?

 What do I mean? Something like:

 rows <- selectEnum ...
 hamletAction [$hamlet|
<html>
 <head>
 <body>
   $for row <- rows
     <p> #{rowDescription row}
   <p .fineprint> (c) Aur Saraf etc' etc'

 That would expand to a monadic action that creates chunks of HTML
while reading the rows Enumerable.

 Is there any serious technological problem with this approach? Or
just choosing a nice extension of Hamlet that would allow running
monadic actions in it like functions are allowed today, without
affecting the simplicity of the API?



Cheers,
 Aur

PS Michael, is it possible in Yesod to have two selectEnum-s "running"
at the same time? Otherwise you'd only be able to work with one query
at a time in this way...

I think it's possible to interleave two enumerators. I suppose it really depends on the database backend: will it allow two queries to run simultaneously. I'm 95% certain that both the PostgreSQL and SQLite backends will perform properly here, though I can't speak for the MongoDB one.

Michael