--- AnyEvent/README 2009/06/23 23:37:32 1.40 +++ AnyEvent/README 2009/06/26 06:33:17 1.41 @@ -382,10 +382,12 @@ them *after* the child process was created, and this means the process could have exited already (and no SIGCHLD will be sent anymore). - Not all event models handle this correctly (POE doesn't), but even for - event models that *do* handle this correctly, they usually need to be - loaded before the process exits (i.e. before you fork in the first - place). + Not all event models handle this correctly (neither POE nor IO::Async + do, see their AnyEvent::Impl manpages for details), but even for event + models that *do* handle this correctly, they usually need to be loaded + before the process exits (i.e. before you fork in the first place). + AnyEvent's pure perl event loop handles all cases correctly regardless + of when you start the watcher. This means you cannot create a child watcher as the very first thing in an AnyEvent program, you *have* to create at least one watcher before @@ -699,6 +701,10 @@ AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse. AnyEvent::Impl::POE based on POE, not generic enough for full support. + # warning, support for IO::Async is only partial, as it is too broken + # and limited toe ven support the AnyEvent API. See AnyEvent::Impl::Async. + AnyEvent::Impl::IOAsync based on IO::Async, cannot be autoprobed (see its docs). + 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 @@ -908,11 +914,11 @@ argument checking is very costly. Setting this variable to a true value will cause AnyEvent to load "AnyEvent::Strict" and then to thoroughly check the arguments passed to most method calls. If it - finds any problems it will croak. + finds any problems, it will croak. In other words, enables "strict" mode. - Unlike "use strict", it is definitely recommended ot keep it off in + Unlike "use strict", it is definitely recommended to keep it off in production. Keeping "PERL_ANYEVENT_STRICT=1" in your environment while developing programs can be very useful, however. @@ -1210,6 +1216,8 @@ Perl/Any 100000 452 4.13 0.73 0.95 pure perl implementation Event/Event 16000 517 32.20 31.80 0.81 Event native interface Event/Any 16000 590 35.85 31.55 1.06 Event + AnyEvent watchers + IOAsync/Any 16000 989 38.10 32.77 11.13 via IO::Async::Loop::IO_Poll + IOAsync/Any 16000 990 37.59 29.50 10.61 via IO::Async::Loop::Epoll Glib/Any 16000 1357 102.33 12.31 51.00 quadratic behaviour Tk/Any 2000 1860 27.20 66.31 14.00 SEGV with >> 2000 watchers POE/Event 2000 6328 109.99 751.67 14.02 via POE::Loop::Event @@ -1249,6 +1257,9 @@ The "Event" module has a relatively high setup and callback invocation cost, but overall scores in on the third place. + "IO::Async" performs admirably well, about on par with "Event", even + when using its pure perl backend. + "Glib"'s memory usage is quite a bit higher, but it features a faster callback invocation and overall ends up in the same class as "Event". However, Glib scales extremely badly, doubling the number of watchers @@ -1328,12 +1339,14 @@ and creating a new one that moves the timeout into the future. Results - name sockets create request - EV 20000 69.01 11.16 - Perl 20000 73.32 35.87 - Event 20000 212.62 257.32 - Glib 20000 651.16 1896.30 - POE 20000 349.67 12317.24 uses POE::Loop::Event + name sockets create request + EV 20000 69.01 11.16 + Perl 20000 73.32 35.87 + IOAsync 20000 157.00 98.14 epoll + IOAsync 20000 159.31 616.06 poll + Event 20000 212.62 257.32 + Glib 20000 651.16 1896.30 + POE 20000 349.67 12317.24 uses POE::Loop::Event Discussion This benchmark *does* measure scalability and overall performance of the @@ -1345,6 +1358,9 @@ Perl surprisingly comes second. It is much faster than the C-based event loops Event and Glib. + IO::Async performs very well when using its epoll backend, and still + quite good compared to Glib when using its pure perl backend. + Event suffers from high setup time as well (look at its code and you will understand why). Callback invocation also has a high overhead compared to the "$_->() for .."-style loop that the Perl event loop @@ -1409,16 +1425,16 @@ could be misinterpreted to make AnyEvent look bad. In fact, the benchmark simply compares IO::Lambda with POE, and IO::Lambda looks better (which shouldn't come as a surprise to anybody). As such, the - benchmark is fine, and shows that the AnyEvent backend from IO::Lambda - isn't very optimal. But how would AnyEvent compare when used without the - extra baggage? To explore this, I wrote the equivalent benchmark for - AnyEvent. + benchmark is fine, and mostly shows that the AnyEvent backend from + IO::Lambda isn't very optimal. But how would AnyEvent compare when used + without the extra baggage? To explore this, I wrote the equivalent + benchmark for AnyEvent. The benchmark itself creates an echo-server, and then, for 500 times, connects to the echo server, sends a line, waits for the reply, and then creates the next connection. This is a rather bad benchmark, as it - doesn't test the efficiency of the framework, but it is a benchmark - nevertheless. + doesn't test the efficiency of the framework or much non-blocking I/O, + but it is a benchmark nevertheless. name runtime Lambda/select 0.330 sec @@ -1434,33 +1450,32 @@ AnyEvent/EV/nb 0.068 sec +state machine 0.134 sec - The benchmark is also a bit unfair (my fault) - the IO::Lambda + The benchmark is also a bit unfair (my fault): the IO::Lambda/POE benchmarks actually make blocking connects and use 100% blocking I/O, defeating the purpose of an event-based solution. All of the newly written AnyEvent benchmarks use 100% non-blocking connects (using AnyEvent::Socket::tcp_connect and the asynchronous pure perl DNS - resolver), so AnyEvent is at a disadvantage here as non-blocking + resolver), so AnyEvent is at a disadvantage here, as non-blocking connects generally require a lot more bookkeeping and event handling than blocking connects (which involve a single syscall only). The last AnyEvent benchmark additionally uses AnyEvent::Handle, which - offers similar expressive power as POE and IO::Lambda (using - conventional Perl syntax), which means both the echo server and the - client are 100% non-blocking w.r.t. I/O, further placing it at a - disadvantage. - - As you can see, AnyEvent + EV even beats the hand-optimised "raw sockets - benchmark", while AnyEvent + its pure perl backend easily beats - IO::Lambda and POE. + offers similar expressive power as POE and IO::Lambda, using + conventional Perl syntax. This means that both the echo server and the + client are 100% non-blocking, further placing it at a disadvantage. + + As you can see, the AnyEvent + EV combination even beats the + hand-optimised "raw sockets benchmark", while AnyEvent + its pure perl + backend easily beats IO::Lambda and POE. And even the 100% non-blocking version written using the high-level (and - slow :) AnyEvent::Handle abstraction beats both POE and IO::Lambda, even - thought it does all of DNS, tcp-connect and socket I/O in a non-blocking - way. - - The two AnyEvent benchmarks can be found as eg/ae0.pl and eg/ae2.pl in - the AnyEvent distribution, the remaining benchmarks are part of the - IO::lambda distribution and were used without any changes. + slow :) AnyEvent::Handle abstraction beats both POE and IO::Lambda by a + large margin, even though it does all of DNS, tcp-connect and socket I/O + in a non-blocking way. + + The two AnyEvent benchmarks programs can be found as eg/ae0.pl and + eg/ae2.pl in the AnyEvent distribution, the remaining benchmarks are + part of the IO::lambda distribution and were used without any changes. SIGNALS AnyEvent currently installs handlers for these signals: @@ -1470,6 +1485,9 @@ emulation for event loops that do not support them natively. Also, some event loops install a similar handler. + If, when AnyEvent is loaded, SIGCHLD is set to IGNORE, then AnyEvent + will reset it to default, to avoid losing child exit statuses. + SIGPIPE A no-op handler is installed for "SIGPIPE" when $SIG{PIPE} is "undef" when AnyEvent gets loaded. @@ -1514,6 +1532,10 @@ is probably even less useful to an attacker than PERL_ANYEVENT_MODEL), and $ENV{PERL_ANYEVENT_STRICT}. + Note that AnyEvent will remove *all* environment variables starting with + "PERL_ANYEVENT_" from %ENV when it is loaded while taint mode is + enabled. + BUGS Perl 5.8 has numerous memleaks that sometimes hit this module and are hard to work around. If you suffer from memleaks, first upgrade to Perl