Hi, I've messed around with Hunchentoot before a good bit, but this week launched my first real site with a moderate number of visitors (http://twitterbuzz.com - hunchentoot/mod_proxy). Now, the site seemed slightly sluggish, but at first I was inclined to blame this on the page generation. Looking closer, though, the page generation happens practically instantly, and the slowness seems to turn up in sending the data back to the user. Playing with apache-bench, I found that transfer speed seems to cap out at about 250KB/s, even when just sending a huge static page (a largish ebook off Gutenburg).
For the moment, I've shifted the site to using tbnl (with mod_lisp), and things seem to run faster; ab can now download the ebook at about 30MB/s, and page loading on the site itself seems snappier. However, I'm aware that tbnl is deprecated.
Is this something silly I'm doing, or an inherent limitation of hunchentoot/flexi-streams? Also, are there any major issues with tbnl I should be aware of?
I'm particularly concerned about this because I'm currently moving a far larger site with lots of users to lisp, and I suspect that the speed problem would be a real issue with it. Rob
Hi,
On Wed, 21 Mar 2007 19:24:34 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
I've messed around with Hunchentoot before a good bit, but this week launched my first real site with a moderate number of visitors (http://twitterbuzz.com - hunchentoot/mod_proxy). Now, the site seemed slightly sluggish, but at first I was inclined to blame this on the page generation. Looking closer, though, the page generation happens practically instantly, and the slowness seems to turn up in sending the data back to the user. Playing with apache-bench, I found that transfer speed seems to cap out at about 250KB/s, even when just sending a huge static page (a largish ebook off Gutenburg).
For the moment, I've shifted the site to using tbnl (with mod_lisp), and things seem to run faster; ab can now download the ebook at about 30MB/s, and page loading on the site itself seems snappier. However, I'm aware that tbnl is deprecated.
Is this something silly I'm doing, or an inherent limitation of hunchentoot/flexi-streams? Also, are there any major issues with tbnl I should be aware of?
I'm particularly concerned about this because I'm currently moving a far larger site with lots of users to lisp, and I suspect that the speed problem would be a real issue with it.
It would surely help if you could give us some info, like what Lisp you are using, which operating system you're on, the usual stuff... Also, maybe you can isolate a bit of stand-alone code (maybe the single page you're talking about) so I can easily reproduce your problems.
Having said that, you are aware of the sentence
"Make sure to use the /newest/ versions of all of these libraries"
in the installation instructions, aren't you? One of the culprits for slow responses in the past has been FLEXI-STREAMS, but that should be mostly fixed in newer releases. (Or maybe not, but it's hard to say without any data provided.)
Cheers, Edi.
On 3/21/07, Edi Weitz edi@agharta.de wrote:
Hi,
It would surely help if you could give us some info, like what Lisp you are using, which operating system you're on, the usual stuff... Also, maybe you can isolate a bit of stand-alone code (maybe the single page you're talking about) so I can easily reproduce your problems.
Having said that, you are aware of the sentence
"Make sure to use the /newest/ versions of all of these libraries"
in the installation instructions, aren't you? One of the culprits for slow responses in the past has been FLEXI-STREAMS, but that should be mostly fixed in newer releases. (Or maybe not, but it's hard to say without any data provided.)
Cheers, Edi. _______________________________________________ tbnl-devel site list
Sorry about that, yes. SBCL 1, Linux. All dependencies are newest available, as is Hunchentoot. The function which just sent back a big file was simply: (defun speedtest () *big-string*)
where *big-string* contained the contents of a 700kb text file. Rob
On Wed, 21 Mar 2007 20:57:12 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
The function which just sent back a big file was simply:
(defun speedtest () *big-string*)
where *big-string* contained the contents of a 700kb text file.
OK, I see. The culprit /is/ FLEXI-STREAMS, but there's not much to do about it in the general case. Its WRITE-SEQUENCE function gets a string and loops through it element by element calling WRITE-CHAR for each one in turn. This is necessary because a) the sequences you can output with FLEXI-STREAMS can be almost anything, even lists or vectors containing a mixture of octets and characters and b) you can't know in advance whether you'll have encoding errors further down the string.
I have a crude optimization for some special cases which I'll release one of these days, but it is just that - a crude optimization for special cases.
To solve your problem there are at least two ways, though:
1. To output a static file you shouldn't keep the file in memory anyway - use CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER instead (or see HANDLE-STATIC-FILE).
2. If you insist on using a variable like above and you know its contents in advance, convert it to an array of element type FLEX:OCTET, i.e. (UNSIGNED-BYTE 8), and let the handler return this array. (This is the only "optimization" that'll always work with FLEXI-STREAMS.)
In both cases, the transfer rate should be in the ballpark of Apache handling static files. Let us know if it's not.
HTH, Edi.
On 3/21/07, Edi Weitz edi@agharta.de wrote:
On Wed, 21 Mar 2007 20:57:12 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
The function which just sent back a big file was simply:
(defun speedtest () *big-string*)
where *big-string* contained the contents of a 700kb text file.
OK, I see. The culprit /is/ FLEXI-STREAMS, but there's not much to do about it in the general case. Its WRITE-SEQUENCE function gets a string and loops through it element by element calling WRITE-CHAR for each one in turn. This is necessary because a) the sequences you can output with FLEXI-STREAMS can be almost anything, even lists or vectors containing a mixture of octets and characters and b) you can't know in advance whether you'll have encoding errors further down the string.
I have a crude optimization for some special cases which I'll release one of these days, but it is just that - a crude optimization for special cases.
To solve your problem there are at least two ways, though:
To output a static file you shouldn't keep the file in memory anyway - use CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER instead (or see HANDLE-STATIC-FILE).
If you insist on using a variable like above and you know its contents in advance, convert it to an array of element type FLEX:OCTET, i.e. (UNSIGNED-BYTE 8), and let the handler return this array. (This is the only "optimization" that'll always work with FLEXI-STREAMS.)
In both cases, the transfer rate should be in the ballpark of Apache handling static files. Let us know if it's not.
HTH, Edi. _______________________________________________ tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
I was really just using the big static file to demonstrate the problem; it's visible when sending dynamically generated pages as well, but just not by so huge a margin (because the pages aren't as big, I think; the bigger the page, the more the speed difference between tbnl and hunchentoot seems to be). Rob
I was really just using the big static file to demonstrate the problem; it's visible when sending dynamically generated pages as well, but just not by so huge a margin (because the pages aren't as big, I think; the bigger the page, the more the speed difference between tbnl and hunchentoot seems to be). Rob
Do you mean that there is a non-linear dependency? How hard / useful would it be to measure the difference between tbnl and hunchentoot for pages of size 1 - N MBs?
-- Gary Warren King, metabang.com Cell: (413) 885 9127 Fax: (206) 338-4052 gwkkwg on Skype * garethsan on AIM
On 3/22/07, Gary King gwking@metabang.com wrote:
Do you mean that there is a non-linear dependency? How hard / useful would it be to measure the difference between tbnl and hunchentoot for pages of size 1 - N MBs?
--
No, as far as I can see there's more or less a linear dependency. The bigger a page is the longer it seems to take to send, with transfer rates peaking (on my machine, which isn't very fast) at about 250KB/s. With tbnl, though, this restriction doesn't seem to exist, and transfer rates can hit multiple megabytes per second.
It would be quite easy to measure, but I'm not sure how useful it would be. Rob
On Thu, 22 Mar 2007 13:32:30 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
With tbnl, though, this restriction doesn't seem to exist
See the explanation I sent yesterday.
It would be quite easy to measure, but I'm not sure how useful it would be.
I agree; I wasn't clear to me from your description whether it was linear or non-linear... thanks.
-- Gary Warren King, metabang.com Cell: (413) 885 9127 Fax: (206) 338-4052 gwkkwg on Skype * garethsan on AIM
On Thu, 22 Mar 2007 12:39:40 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
I was really just using the big static file to demonstrate the problem; it's visible when sending dynamically generated pages as well, but just not by so huge a margin (because the pages aren't as big, I think; the bigger the page, the more the speed difference between tbnl and hunchentoot seems to be).
I've just uploaded a new release of FLEXI-STREAMS (0.11.1) which incorporates the patches I was talking about. This should make Hunchentoot output significantly faster /if/ you're using an 8-bit encoding without line encoding conversions (like the default format), but it'll still be an order of magnitude slower than writing binary data directly to the stream.
Let us know if this helps.
I'm happy to accept reasonable patches to make FLEXI-STREAMS faster, but obviously there's a certain price you have to pay for flexibility and portability.
Note that you can of course bypass FLEXI-STREAMS if you absolutely need the speed. Something like this (untested):
(defun my-handler () ;; no need to generate the content before calling SEND-HEADERS, ;; but that way your errors will be handled by Hunchentoot (let ((content (generate-content)) (stream (flexi-stream-stream (send-headers)))) (write-sequence (maybe-convert content) stream)))
Try it...
STREAM will either be the raw socket stream or a chunked stream from Chunga depending on how you've started your server. (You can put Hunchentoot behind mod_lisp and use :INPUT-CHUNKING-P NIL and :MOD-LISP-P T to bypass Chunga as well.)
On 3/22/07, Edi Weitz edi@agharta.de wrote:
On Thu, 22 Mar 2007 12:39:40 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
I was really just using the big static file to demonstrate the problem; it's visible when sending dynamically generated pages as well, but just not by so huge a margin (because the pages aren't as big, I think; the bigger the page, the more the speed difference between tbnl and hunchentoot seems to be).
I've just uploaded a new release of FLEXI-STREAMS (0.11.1) which incorporates the patches I was talking about. This should make Hunchentoot output significantly faster /if/ you're using an 8-bit encoding without line encoding conversions (like the default format), but it'll still be an order of magnitude slower than writing binary data directly to the stream.
Let us know if this helps.
I'm happy to accept reasonable patches to make FLEXI-STREAMS faster, but obviously there's a certain price you have to pay for flexibility and portability.
Note that you can of course bypass FLEXI-STREAMS if you absolutely need the speed. Something like this (untested):
(defun my-handler () ;; no need to generate the content before calling SEND-HEADERS, ;; but that way your errors will be handled by Hunchentoot (let ((content (generate-content)) (stream (flexi-stream-stream (send-headers)))) (write-sequence (maybe-convert content) stream)))
Try it...
STREAM will either be the raw socket stream or a chunked stream from Chunga depending on how you've started your server. (You can put Hunchentoot behind mod_lisp and use :INPUT-CHUNKING-P NIL and :MOD-LISP-P T to bypass Chunga as well.) _______________________________________________ tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
Hi, This works perfectly; it's nearly as fast as tbnl, and certainly fast enough that it's not a worry; when putting together my new site, I know it's there to fall back on if speed does become an issue. Thanks Rob
On Fri, 23 Mar 2007 00:23:55 +0000, "Robert Synnott" rsynnott@gmail.com wrote:
This works perfectly; it's nearly as fast as tbnl, and certainly fast enough that it's not a worry;
Which one? Using the new FLEXI-STREAMS release or bypassing it?