POE 1.280 is Faster

rcaputo on 2009-10-14T05:19:58

POE 1.280 has just been released, but it may take up to a day before your favorite CPAN mirror catches wind of it. You'll also need the latest POE::Test::Loops, version 1.030.

Those following along may notice that the version numbers jumped a little. That's because POE has undergone a couple optimizations that alter its behavior a little.

I/O Dispatch is Faster

I/O events jump the queue in POE 1.280. Skipping an enqueue and dequeue saves significant time. The drawback is that I/O is dispatched in a different order relative to other kinds of events. Most people won't care, but it has affected one of POE::Component::Client::HTTP's tests. See below for contact information if you think it's affected you.

Session Cleanup is Faster

In POE 1.280, session cleanup is done just before the event loop would wait for new events. Programs that aren't event bound should show decreased latency because the cleanup will be scheduled during idle times. This optimization changes the timing of session cleanup and their resulting _stop events. While I don't think it affects many people, it has already bitten Adam Kennedy. Please let us know if you suspect it's gnawing on you, too.

Staying in Touch

People who need realtime notice of POE changes may watch them at SourceForge, Ohlo and CIA.

POE's community may be found everywhere. Several members tend to accumulate in POE's mailing list and IRC channel at irc.perl.org #poe. You're welcome to join us, even if you don't have problems to report.

Thank you.


Benchmarks!

Alias on 2009-10-15T05:19:59

So, how MUCH faster? :)

I/O dispatch is about 130% faster, since you ask.

rcaputo on 2009-10-15T17:05:43

Sorry, no fancy graphs.

I wrote a deliberately simple program to count select_read() events per second. I ran it five times for each version of POE, averaged the results, and calculated the improvement using (new_rate/old_rate-1). Standard deviation for the sample sets were about 1%, if that matters.

#!/usr/bin/env perl

use warnings;
use strict;

use POE;

my $limit = 10_000;
my @start_times;
my @end_times;
my $count = 0;

my $filehandle;

POE::Session->create(
  inline_states => {
    _start => sub {
      open $filehandle, "<", "/dev/zero" or die $!;
      $_[KERNEL]->select_read($filehandle, "count");
      @start_times = times();
    },
    count  => sub {
      if ($count < $limit) {
        $count++;
        return;
      }

      @end_times = times();
      for (0..$#end_times) {
        $end_times[$_] -= $start_times[$_];
      }

      $_[KERNEL]->select_read($filehandle, undef);
    },
  },
);

POE::Kernel->run();

print join("\t", "POE", "BENCH", "COUNT", "RATE"), "\n";
print join(
  "\t",
  $POE::VERSION,
  "io/cpusec",
  $limit,
  sprintf("%.2f", $limit / ($end_times[0] + $end_times[1])),
), "\n";

I don't have a methodology to test the mark-and-sweep garbage collection in isolation. Got any ideas?