Re: Performance tunning for POE/Component::Client::HTTP

Rocco Caputo <[email protected]> Fri, 11 Jun 2010 14:19:01 -0400
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
It's not unheard of for Perl code to be 10x slower (or more) than C.   
Still, a bit of Devel::NYTProf and optimization may be in order.

Is ab pre-resolving and caching the host address?  I'm pretty sure the  
Perl version isn't optimized for benchmarking loads from a single  
address, but if you replace the host with an IP address it should skip  
the resolver step.

The last few responses take the longest to arrive.  I've added a  
time() stamp and the response code to your output:

1276277210 (404) = 990
1276277210 (404) = 991
1276277210 (404) = 992
1276277210 (404) = 993
1276277210 (404) = 994
1276277211 (404) = 995
1276277211 (404) = 996
1276277211 (404) = 997
1276277212 (404) = 998
1276277212 (404) = 999
1276277227 (404) = 1000

Tweaking the Keepalive parameters seems to help a little bit.  This  
seems a bit faster for me:

my $url = "http://216.115.98.241/2.8.1/build/fonts/fonts-min.css";

my $pool = POE::Component::Client::Keepalive->new(
     keep_alive   => 1,
     max_open     => 2000,
     max_per_host => 2000,
     timeout      => 120,
);

...

1276277530 (404) = 988
1276277530 (404) = 989
1276277530 (404) = 990
1276277530 (404) = 991
1276277530 (404) = 992
1276277530 (404) = 993
1276277531 (404) = 994
1276277531 (404) = 995
1276277531 (404) = 996
1276277531 (404) = 997
1276277531 (404) = 998
1276277532 (404) = 999
1276277532 (404) = 1000

The Client::Keepalive tweaks are disturbing.  From the response  
headers, it looks like Client::Keepalive shouldn't be holding onto  
sockets anyway:

1) macbookpoe:~/projects/misc/support% curl -D - http://216.115.98.241/2.8.1/build/fonts/fonts-min.css
HTTP/1.1 404 Not Found
Date: Fri, 11 Jun 2010 17:34:25 GMT
Connection: close
Server: YTS/1.17.23.1
Cache-Control: no-store
Content-Type: text/html
Content-Language: en
Content-Length: 176

TODO: Verify whether Client::Keepalive (and/or Client::HTTP) socket  
cleanup paths for "Connection: close" transactions are optimal.

It could also be socket buffer congestion on the client.  On my OSX box:

1) macbookpoe:~% netstat -n|grep -c LAST_ACK
314

The POE benchmark is waiting for ACKs from the server, which is  
slowing things down.  This is platform and version dependent, so your  
mileage may vary.  For instance, you might have 300+ TIME_WAIT sockets  
instead, or your system could be tweaked to quickly recycle sockets.

Anyway, if this isn't happening with ab, it means that Client::HTTP is  
doing something different.  Possibly something that isn't optimal for  
benchmarking purposes.  Be aware that "optimal" may conflict with  
"correct".  Benchmarks are permitted certain liberties that general- 
purpose libraries are not.  Unfortunately for benchmarks, "correct"  
takes precedence.

Which is not to say that Client::HTTP and Client::Keepalive are  
actually correct here.  That's still to be seen.

I'd appreciate it if you could dig into the problem a little deeper.   
I have some digging of my own to do, but I'm currently swamped.

-- 
Rocco Caputo - [email protected]


On Jun 9, 2010, at 11:52, Ryan Chan wrote:

> Hello,
>
> I have a simple code at: http://pastebin.com/KeU4XANP
>
> This script down a small CSS file from Yahoo CDN for 1000 times, I
> benchmarked this script with ApacheBench(ab)
>
> POE/Component::Client::HTTP: 70 requests / sec
> ab (ab -n 1000 -c 100
> 'http://yui.yahooapis.com/2.8.1/build/fonts/fonts-min.css'): 500
> requests /sec
>
> Since ab is running as single threaded mode, but still 7-8x faster
> than  POE/Component::Client::HTTP.
>
> Is this result normal?