--- AnyEvent/lib/AnyEvent.pm 2008/04/24 03:24:07 1.58 +++ AnyEvent/lib/AnyEvent.pm 2008/04/25 06:54:08 1.64 @@ -2,7 +2,7 @@ AnyEvent - provide framework for multiple event loops -EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt - various supported event loops +EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event loops =head1 SYNOPSIS @@ -80,11 +80,12 @@ module. During the first call of any watcher-creation method, the module tries -to detect the currently loaded event loop by probing whether one of -the following modules is already loaded: L, L, -L, L, L, L, L, L. The first one -found is used. If none are found, the module tries to load these modules -(excluding Event::Lib and Qt) in the order given. The first one that can +to detect the currently loaded event loop by probing whether one of the +following modules is already loaded: L, L, L, +L, L, L, L, L, L, +L. The first one found is used. If none are found, the module tries +to load these modules (excluding Event::Lib, Qt and POE as the pure perl +adaptor should always succeed) in the order given. The first one that can be successfully loaded will be used. If, after this, still none could be found, AnyEvent will fall back to a pure-perl event loop, which is not very efficient, but should work everywhere. @@ -364,6 +365,17 @@ AnyEvent::Impl::Perl pure-perl implementation, inefficient but portable. AnyEvent::Impl::Qt based on Qt, cannot be autoprobed (see its docs). AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse. + AnyEvent::Impl::POE based on POE, not generic enough for full support. + +There is no support for WxWidgets, as WxWidgets has no support for +watching file handles. However, you can use WxWidgets through the +POE Adaptor, as POE has a Wx backend that simply polls 20 times per +second, which was considered to be too horrible to even consider for +AnyEvent. Likewise, other POE backends can be used by AnyEvent by using +it's adaptor. + +AnyEvent knows about L and L and will try to use L when +autodetecting them. =item AnyEvent::detect @@ -424,7 +436,7 @@ use Carp; -our $VERSION = '3.12'; +our $VERSION = '3.3'; our $MODEL; our $AUTOLOAD; @@ -441,11 +453,13 @@ [Event:: => AnyEvent::Impl::Event::], [Glib:: => AnyEvent::Impl::Glib::], [Tk:: => AnyEvent::Impl::Tk::], + [Wx:: => AnyEvent::Impl::POE::], + [Prima:: => AnyEvent::Impl::POE::], [AnyEvent::Impl::Perl:: => AnyEvent::Impl::Perl::], -); -my @models_detect = ( - [Qt:: => AnyEvent::Impl::Qt::], # requires special main program + # everything below here will not be autoprobed as the pureperl backend should work everywhere [Event::Lib:: => AnyEvent::Impl::EventLib::], # too buggy + [Qt:: => AnyEvent::Impl::Qt::], # requires special main program + [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza ); our %method = map +($_ => 1), qw(io timer signal child condvar broadcast wait one_event DESTROY); @@ -459,12 +473,14 @@ if (eval "require $model") { $MODEL = $model; warn "AnyEvent: loaded model '$model' (forced by \$PERL_ANYEVENT_MODEL), using it.\n" if $verbose > 1; + } else { + warn "AnyEvent: unable to load model '$model' (from \$PERL_ANYEVENT_MODEL):\n$@" if $verbose; } } # check for already loaded models unless ($MODEL) { - for (@REGISTRY, @models, @models_detect) { + for (@REGISTRY, @models) { my ($package, $model) = @$_; if (${"$package\::VERSION"} > 0) { if (eval "require $model") { @@ -661,6 +677,14 @@ =item C +By default, AnyEvent will be completely silent except in fatal +conditions. You can set this environment variable to make AnyEvent more +talkative. + +When set to C<1> or higher, causes AnyEvent to warn about unexpected +conditions, such as not being able to load the event model specified by +C. + When set to C<2> or higher, cause AnyEvent to report to STDERR which event model it chooses. @@ -838,6 +862,79 @@ $quit->wait; + +=head1 BENCHMARK + +To give you an idea of the performance an doverheads that AnyEvent adds +over the backends, here is a benchmark of various supported backends. The +benchmark creates a lot of timers (with zero timeout) and io events +(watching STDOUT, a pty, to become writable). + +Explanation of the fields: + +I is the number of event watchers created/destroyed. Sicne +different event models have vastly different performance each backend was +handed a number of watchers so that overall runtime is acceptable and +similar to all backends (and keep them from crashing). + +I is the number of bytes (as measured by resident set size) used by +each watcher. + +I is the time, in microseconds, to create a single watcher. + +I is the time, in microseconds, used to invoke a simple callback +that simply counts down. + +I is the time, in microseconds, to destroy a single watcher. + + name watcher bytes create invoke destroy comment + EV/EV 400000 244 0.56 0.46 0.31 EV native interface + EV/Any 100000 610 3.52 0.91 0.75 + CoroEV/Any 100000 610 3.49 0.92 0.75 coroutines + Coro::Signal + Perl/Any 10000 654 4.64 1.22 0.77 pure perl implementation + Event/Event 10000 523 28.05 21.38 5.22 Event native interface + Event/Any 10000 943 34.43 20.48 1.39 + Glib/Any 16000 1357 96.99 12.55 55.51 quadratic behaviour + Tk/Any 2000 1855 27.01 66.61 14.03 SEGV with >> 2000 watchers + POE/Select 2000 6343 94.69 807.65 562.69 POE::Loop::Select + POE/Event 2000 6644 108.15 768.19 14.33 POE::Loop::Event + +Discussion: The benchmark does I bench scalability of the +backend. For example a select-based backend (such as the pureperl one) can +never compete with a backend using epoll. In this benchmark, only a single +filehandle is used. + +EV is the sole leader regarding speed and memory use, which are both +maximal/minimal. Even when going through AnyEvent, there is only one event +loop that uses less memory (the Event module natively), and no faster +event model. + +The pure perl implementation is hit in a few sweet spots (both the +zero timeout and the use of a single fd hit optimisations in the perl +interpreter and the backend itself), but it shows that it adds very little +overhead in itself. Like any select-based backend it's performance becomes +really bad with lots of file descriptors. + +The Event module has a relatively high setup and callback invocation cost, +but overall scores on the third place. + +Glib has a little higher memory cost, a bit fster callback invocation and +has a similar speed as Event. + +The Tk backend works relatively well, the fact that it crashes with +more than 2000 watchers is a big setback, however, as correctness takes +precedence over speed. + +POE, regardless of backend (wether it's pure perl select backend or the +Event backend) shows abysmal performance and memory usage: Watchers use +almost 30 times as much memory as EV watchers, and 10 times as much memory +as both Event or EV via AnyEvent. + +Summary: using EV through AnyEvent is faster than any other event +loop. The overhead AnyEvent adds can be very small, and you should avoid +POE like the plague if you want performance or reasonable memory usage. + + =head1 FORK Most event libraries are not fork-safe. The ones who are usually are @@ -846,6 +943,7 @@ If you have to fork, you must either do so I creating your first watcher OR you must not use AnyEvent at all in the child. + =head1 SECURITY CONSIDERATIONS AnyEvent can be forced to load any event model via @@ -862,19 +960,21 @@ use AnyEvent; + =head1 SEE ALSO Event modules: L, L, L, L, L, L, L, L, L, L, -L, L. +L, L, L. Implementations: L, L, L, L, L, L, L, L, -L. +L, L. Nontrivial usage examples: L, L. + =head1 AUTHOR Marc Lehmann