--- AnyEvent/lib/AnyEvent.pm 2008/04/24 03:19:28 1.57 +++ AnyEvent/lib/AnyEvent.pm 2008/04/25 06:58:38 1.67 @@ -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. @@ -209,15 +210,16 @@ in 10 seconds") and based on wallclock time (absolute, "fire at 12 o'clock"). -While most event loops expect timers to specified in a relative way, they use -absolute time internally. This makes a difference when your clock "jumps", -for example, when ntp decides to set your clock backwards from the wrong 2014-01-01 to -2008-01-01, a watcher that you created to fire "after" a second might actually take -six years to finally fire. +While most event loops expect timers to specified in a relative way, they +use absolute time internally. This makes a difference when your clock +"jumps", for example, when ntp decides to set your clock backwards from +the wrong date of 2014-01-01 to 2008-01-01, a watcher that is supposed to +fire "after" a second might actually take six years to finally fire. AnyEvent cannot compensate for this. The only event loop that is conscious -about these issues is L, which offers both relative (ev_timer) and -absolute (ev_periodic) timers. +about these issues is L, which offers both relative (ev_timer, based +on true relative time) and absolute (ev_periodic, based on wallclock time) +timers. AnyEvent always prefers relative timers, if available, matching the AnyEvent API. @@ -228,7 +230,7 @@ I without any C prefix, C is the Perl callback to be invoked whenever a signal occurs. -Multiple signals occurances can be clumped together into one callback +Multiple signal occurances can be clumped together into one callback invocation, and callback invocation will be synchronous. synchronous means that it might take a while until the signal gets handled by the process, but it is guarenteed not to interrupt any other callbacks. @@ -363,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 @@ -423,7 +436,7 @@ use Carp; -our $VERSION = '3.12'; +our $VERSION = '3.3'; our $MODEL; our $AUTOLOAD; @@ -440,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); @@ -458,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") { @@ -660,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. @@ -837,6 +862,81 @@ $quit->wait; + +=head1 BENCHMARK + +To give you an idea of the performance and overheads that AnyEvent adds +over the backends directly, here is a benchmark of various supported event +models natively and with anyevent. The benchmark creates a lot of timers +(with a zero timeout) and io watchers (watching STDOUT, a pty, to become +writable, which it is), lets them fire exactly once and destroys them +again. + +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 @@ -845,6 +945,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 @@ -861,19 +962,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