Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Slow performance of non-blocking select?

by PMCarl (Initiate)
on Nov 04, 2012 at 21:22 UTC ( #1002245=perlquestion: print w/replies, xml ) Need Help??
PMCarl has asked for the wisdom of the Perl Monks concerning the following question:

Hello Wise Ones, I'm running into a problem using non-blocking pipes: The select and can_read methods are taking ~300Ás/call (according to NYTProf). Is that normal? It is really killing the performance of my app.

You can see my package at:
I'm new to pipe communication in Perl, so it's very likely that "I'm using it wrong" (yeah, I know, that's what she said)

I'd be happy to take feedback even if it's not related to the performance


I have re-written the Parallel::Fork::BossWorker ( package to support some features that I think are rather critical:

* Messages larger than the pipe buffer, which is 64K on most platforms. The current implementation silently corrupts the data if it's larger than the buffer.

* Asynchronous processing: The current implementation only supports one big batch of processing. I've added a `progress` sub.

Unfortunately, these features require a complete re-write because the current code exploits a feature of pipes where any messages smaller than the buffer are atomic. So the current code can share pipes and doesn't need to manage buffers.

My test is currently taking 50% longer than the original version, which is exactly the amount of time being spent in using select/can_read.

Replies are listed 'Best First'.
Re: Slow performance of non-blocking select?
by zentara (Archbishop) on Nov 05, 2012 at 10:26 UTC
Re: Slow performance of non-blocking select?
by flexvault (Monsignor) on Nov 05, 2012 at 16:31 UTC

    Welcome PMCarl,

    You don't mention what operating system you're using, but a few things differ greatly with the operating systems I have testing with.

    When using 'can_read', I pass 3.025 seconds as:

    my @ready = $select->can_read(3.025);
    Your comments in your code says it waits the full time so you use 'sleep' with a small time-out. If the above did that, then I would only be able to process 19 transactions per minute. If fact on different *nix systems I process between 8,000 and 38,000 transactions per second per core. So it may be a problem with your platform. Why '3.025' because I started with '.025' and found that using a larger number got better performance than using a smaller number. So I put a '3' in and got better performance. Could be platform related. YMMV.

    You mention a 'default' of 64K. I have systems with different read/write buffered ranging from 8K to 512K. You should use 'getsockopt' to find your limits, and then I've found that the best performance is to ask the client for their sizes, and return a 'good' value to the client for all communication. Keep in mind that you can use a hash to keep track of the different 'MAXRD/MAXWR' for each client.

    I haven't looked at all of your code, but these items jumped out at me, and since you're trying to improve and generalize the code, maybe this will help.

    Update:I changed '19 transactions per second' to '19 transactions per minute' which would be correct ( 60 seconds / 3.025 seconds ).

    Good Luck!

    "Well done is better than well said." - Benjamin Franklin

      Thanks flexvault!

      My first thought was: "I'm using non-blocking IO::Select objects, so the time-out shouldn't matter"

      ...but that seems to have been the problem. 'can_read' and IO::Select::select both seem to be blocking even though I'm calling $obj->blocking(0);

      By using a very small time-out, I'm able to get very close to the performance of the original version of that package. Some runs actually show the new version out-performing the old one.

      The way the code is structured, it misses time that it could be doing other things while it is being blocked on can_read, so I don't get the advantage that you may be getting.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002245]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2018-06-25 12:19 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (126 votes). Check out past polls.