EV-Future
view release on metacpan or search on metacpan
## Install
```bash
perl Makefile.PL && make && make test
```
Requires Perl 5.14+, EV 4.37+, and a C compiler.
## Benchmarks
1000 sync tasks x 5000 iterations (`bench/comparison.pl`; `race` is not covered by
that script, so it has no row here). Measured with EV 4.37, AnyEvent 7.17,
Future::XS 0.15, Promise::XS 0.21 and Future::Utils 0.52:
| | parallel | parallel_limit(10) | series |
|---|---:|---:|---:|
| EV::Future (unsafe) | 9,259 | 7,692 | 7,692 |
| EV::Future (safe) | 4,098 | 4,032 | 3,968 |
| AnyEvent cv | 1,563 | - | 4,717 |
| Future::XS | 1,563 | 624 | 1,241 |
| Promise::XS | 1,323 | - | 1,157 |
bench/benchmark.pl view on Meta::CPAN
print "Running $name...\n";
my $start = time;
for (1..$ITERATIONS) {
$code->();
}
my $end = time;
my $elapsed = $end - $start;
printf "%-30s: %8.4fs (%10.2f/s)\n", $name, $elapsed, $ITERATIONS / $elapsed;
}
print "Benchmarking $COUNT synchronous tasks over $ITERATIONS iterations:\n";
run_bench('EV::Future::parallel', sub {
EV::Future::parallel(\@tasks, sub { });
});
run_bench('EV::Future::parallel (unsafe)', sub {
EV::Future::parallel(\@tasks, sub { }, 1);
});
run_bench('EV::Future::parallel_limit(10)', sub {
bench/comparison.pl view on Meta::CPAN
}
sub bench_future_fmap_void {
my @items = 1..$COUNT;
my $f = fmap_void {
return Future->done;
} foreach => \@items, concurrent => 10;
$f->get;
}
print "Benchmarking $COUNT tasks ($ITERATIONS iterations):\n";
print "\n--- PARALLEL ---\n";
timethese($ITERATIONS, {
'EV::Future::parallel' => \&bench_ev_future_parallel,
'EV::Future::parallel (unsafe)' => \&bench_ev_future_parallel_unsafe,
'Promise::XS::all' => \&bench_promise_xs_parallel,
'Future::XS::wait_all' => \&bench_future_xs_parallel,
'AnyEvent::cv (begin/end)' => \&bench_anyevent_parallel,
});
lib/EV/Future.pm view on Meta::CPAN
unsafe-mode exception, whose counters freeze instead; see
L</"Safe vs unsafe mode">.
In unsafe mode, double-calling C<done> corrupts the completion counter, so
C<pending> under-reports for C<parallel> and C<parallel_limit> for the same
reason C<final_cb> can fire early. The same double-call can drive the in-flight
count below zero; C<active> is floored at 0 rather than reporting a negative.
=head1 BENCHMARKS
1000 synchronous tasks, 5000 iterations (C<bench/comparison.pl>). The script
covers the task form only, so C<race> and the three map primitives have no
figures here; see L</"Task form versus map form"> below for those. Measured
with EV 4.37, AnyEvent 7.17, Future::XS 0.15, Promise::XS 0.21 and
Future::Utils 0.52.
--- PARALLEL (iterations/sec) ---
EV::Future (unsafe) 9,259
EV::Future (safe) 4,098
AnyEvent::cv (begin/end) 1,563
Future::XS::wait_all 1,563
Promise::XS::all 1,323
--- PARALLEL LIMIT 10 (iterations/sec) ---
EV::Future (unsafe) 7,692
EV::Future (safe) 4,032
Future::Utils::fmap_void 624
--- SERIES (iterations/sec) ---
EV::Future (unsafe) 7,692
AnyEvent::cv (stack-safe) 4,717
EV::Future (safe) 3,968
Future::XS (chain) 1,241
Promise::XS (chain) 1,157
=head2 Task form versus map form
C<bench/map_vs_task.pl>, 100 elements, unsafe mode, as cachegrind instruction
counts per call, which are deterministic where wall-clock timings on a loaded
( run in 1.758 second using v1.01-cache-2.11-cpan-f03e8824b8d )