Data-Monad-CondVar
view release on metacpan or search on metacpan
eg/bench_cv.pl view on Meta::CPAN
use strict;
use warnings;
use Data::Monad::CondVar;
use Data::Monad::Base::Sugar;
use AnyEvent;
use Coro;
use Coro::AnyEvent;
use Benchmark qw(:hireswallclock);
my ($delay, $count) = @ARGV;
$delay //= 0;
$count //= 20000;
sub cv($) {
my $v = shift;
my $cv = AE::cv;
my $t; $t = AE::timer $delay, 0, sub {
$cv->($v);
undef $t;
};
return $cv;
}
sub bare_ae($$) {
my ($cv1, $cv2) = @_;
my $cv = AE::cv;
$cv1->cb(sub {
my $x = eval {$_[0]->recv};
$@ and $cv->croak($@);
$cv2->cb(sub {
my $y = eval {$_[0]->recv};
$@ and $cv->croak($@);
$cv->send($x * $y);
});
});
$cv->recv;
}
sub monad($$) {
my ($cv1, $cv2) = @_;
$cv1->flat_map(sub {
my $x = shift;
$cv2->map(sub {
my $y = shift;
$x * $y;
});
})->recv;
}
sub monad_lift($$) {
my ($cv1, $cv2) = @_;
cv_lift(sub {$_[0] * $_[1]})->($cv1, $cv2)->recv;
}
sub monad_for($$) {
my ($cv1, $cv2) = @_;
Data::Monad::Base::Sugar::for {
pick \my $x => sub { $cv1 };
pick \my $y => sub { $cv2 };
yield {$x * $y};
}->recv;
}
sub coro($$) {
my ($cv1, $cv2) = @_;
async {
my $x = $cv1->recv;
my $y = $cv2->recv;
$x * $y;
}->join;
}
my $r = Benchmark::timethese($count => {
bare_ae => sub { bare_ae(cv 5, cv 4) },
( run in 2.905 seconds using v1.01-cache-2.11-cpan-4ab04211f4c )