--- AnyEvent/lib/AnyEvent.pm 2008/04/25 13:48:42 1.84 +++ AnyEvent/lib/AnyEvent.pm 2008/04/25 14:24:29 1.90 @@ -143,12 +143,16 @@ You can create an I/O watcher by calling the C<< AnyEvent->io >> method with the following mandatory key-value pairs as arguments: -C the Perl I (I file descriptor) to watch for -events. C must be a string that is either C or C, which -creates a watcher waiting for "r"eadable or "w"ritable events, +C the Perl I (I file descriptor) to watch +for events. C must be a string that is either C or C, +which creates a watcher waiting for "r"eadable or "w"ritable events, respectively. C is the callback to invoke each time the file handle becomes ready. +Although the callback might get passed parameters, their value and +presence is undefined and you cannot rely on them. Portable AnyEvent +callbacks cannot use arguments passed to I/O watcher callbacks. + The I/O watcher might use the underlying file descriptor or a copy of it. You must not close a file handle as long as any watcher is active on the underlying file descriptor. @@ -157,10 +161,6 @@ always use non-blocking calls when reading/writing from/to your file handles. -Although the callback might get passed parameters, their value and -presence is undefined and you cannot rely on them. Portable AnyEvent -callbacks cannot use arguments passed to I/O watcher callbacks. - Example: # wait for readability of STDIN, then read a line and disable the watcher @@ -176,17 +176,17 @@ method with the following mandatory arguments: C specifies after how many seconds (fractional values are -supported) should the timer activate. C the callback to invoke in that -case. - -The timer callback will be invoked at most once: if you want a repeating -timer you have to create a new watcher (this is a limitation by both Tk -and Glib). +supported) the callback should be invoked. C is the callback to invoke +in that case. Although the callback might get passed parameters, their value and presence is undefined and you cannot rely on them. Portable AnyEvent callbacks cannot use arguments passed to time watcher callbacks. +The timer callback will be invoked at most once: if you want a repeating +timer you have to create a new watcher (this is a limitation by both Tk +and Glib). + Example: # fire an event after 7.7 seconds @@ -236,6 +236,10 @@ I without any C prefix, C is the Perl callback to be invoked whenever a signal occurs. +Although the callback might get passed parameters, their value and +presence is undefined and you cannot rely on them. Portable AnyEvent +callbacks cannot use arguments passed to signal watcher callbacks. + 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, @@ -259,7 +263,8 @@ watches for any child process exit). The watcher will trigger as often as status change for the child are received. This works by installing a signal handler for C. The callback will be called with the pid -and exit status (as returned by waitpid). +and exit status (as returned by waitpid), so unlike other watcher types, +you I rely on child watcher callback arguments. There is a slight catch to child watchers, however: you usually start them I the child process was created, and this means the process could @@ -961,17 +966,16 @@ natively. 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, and all watchers become ready at the -same time). Nevertheless this shows that it adds very little overhead in -itself. Like any select-based backend its performance becomes really bad -with lots of file descriptors (and few of them active), of course, but -this was not subject of this benchmark. +constant timeout and the use of a single fd hit optimisations in the perl +interpreter and the backend itself). Nevertheless this shows that it +adds very little overhead in itself. Like any select-based backend its +performance becomes really bad with lots of file descriptors (and few of +them active), of course, but this was not subject of this benchmark. -The C module has a relatively high setup and callback invocation cost, -but overall scores on the third place. +The C module has a relatively high setup and callback invocation +cost, but overall scores in on the third place. -C's memory usage is quite a bit bit higher, but it features a +C's memory usage is quite a bit higher, but it features a faster callback invocation and overall ends up in the same class as C. However, Glib scales extremely badly, doubling the number of watchers increases the processing time by more than a factor of four, @@ -984,14 +988,16 @@ precedence over speed. Nevertheless, its performance is surprising, as the file descriptor is dup()ed for each watcher. This shows that the dup() employed by some adaptors is not a big performance issue (it does incur a -hidden memory cost inside the kernel, though, that is not reflected in the -figures above). +hidden memory cost inside the kernel which is not reflected in the figures +above). -C, regardless of underlying event loop (wether using its pure perl -select-based backend or the Event module) 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. Watcher -invocation is almost 900 times slower than with AnyEvent's pure perl +C, regardless of underlying event loop (whether using its pure +perl select-based backend or the Event module, the POE-EV backend +couldn't be tested because it wasn't working) shows abysmal performance +and memory usage: Watchers use almost 30 times as much memory as +EV watchers, and 10 times as much memory as Event (the high memory +requirements are caused by requiring a session for each watcher). Watcher +invocation speed is almost 900 times slower than with AnyEvent's pure perl implementation. The design of the POE adaptor class in AnyEvent can not really account for this, as session creation overhead is small compared to execution of the state machine, which is coded pretty optimally within @@ -999,16 +1005,21 @@ =head2 Summary -Using EV through AnyEvent is faster than any other event loop, but most -event loops have acceptable performance with or without AnyEvent. +=over 4 + +=item * Using EV through AnyEvent is faster than any other event loop +(even when used without AnyEvent), but most event loops have acceptable +performance with or without AnyEvent. -The overhead AnyEvent adds is usually much smaller than the overhead of -the actual event loop, only with extremely fast event loops such as the EV +=item * The overhead AnyEvent adds is usually much smaller than the overhead of +the actual event loop, only with extremely fast event loops such as EV adds AnyEvent significant overhead. -And you should simply avoid POE like the plague if you want performance or +=item * You should avoid POE like the plague if you want performance or reasonable memory usage. +=back + =head1 FORK