… | |
… | |
970 | interpreter and the backend itself). Nevertheless this shows that it |
970 | interpreter and the backend itself). Nevertheless this shows that it |
971 | adds very little overhead in itself. Like any select-based backend its |
971 | adds very little overhead in itself. Like any select-based backend its |
972 | performance becomes really bad with lots of file descriptors (and few of |
972 | performance becomes really bad with lots of file descriptors (and few of |
973 | them active), of course, but this was not subject of this benchmark. |
973 | them active), of course, but this was not subject of this benchmark. |
974 | |
974 | |
975 | The C<Event> module has a relatively high setup and callback invocation cost, |
975 | The C<Event> module has a relatively high setup and callback invocation |
976 | but overall scores on the third place. |
976 | cost, but overall scores in on the third place. |
977 | |
977 | |
978 | C<Glib>'s memory usage is quite a bit bit higher, but it features a |
978 | C<Glib>'s memory usage is quite a bit higher, but it features a |
979 | faster callback invocation and overall ends up in the same class as |
979 | faster callback invocation and overall ends up in the same class as |
980 | C<Event>. However, Glib scales extremely badly, doubling the number of |
980 | C<Event>. However, Glib scales extremely badly, doubling the number of |
981 | watchers increases the processing time by more than a factor of four, |
981 | watchers increases the processing time by more than a factor of four, |
982 | making it completely unusable when using larger numbers of watchers |
982 | making it completely unusable when using larger numbers of watchers |
983 | (note that only a single file descriptor was used in the benchmark, so |
983 | (note that only a single file descriptor was used in the benchmark, so |
… | |
… | |
986 | The C<Tk> adaptor works relatively well. The fact that it crashes with |
986 | The C<Tk> adaptor works relatively well. The fact that it crashes with |
987 | more than 2000 watchers is a big setback, however, as correctness takes |
987 | more than 2000 watchers is a big setback, however, as correctness takes |
988 | precedence over speed. Nevertheless, its performance is surprising, as the |
988 | precedence over speed. Nevertheless, its performance is surprising, as the |
989 | file descriptor is dup()ed for each watcher. This shows that the dup() |
989 | file descriptor is dup()ed for each watcher. This shows that the dup() |
990 | employed by some adaptors is not a big performance issue (it does incur a |
990 | employed by some adaptors is not a big performance issue (it does incur a |
991 | hidden memory cost inside the kernel, though, that is not reflected in the |
991 | hidden memory cost inside the kernel which is not reflected in the figures |
992 | figures above). |
992 | above). |
993 | |
993 | |
994 | C<POE>, regardless of underlying event loop (whether using its pure perl |
994 | C<POE>, regardless of underlying event loop (whether using its pure |
995 | select-based backend or the Event module) shows abysmal performance and |
995 | perl select-based backend or the Event module, the POE-EV backend |
|
|
996 | couldn't be tested because it wasn't working) shows abysmal performance |
996 | memory usage: Watchers use almost 30 times as much memory as EV watchers, |
997 | and memory usage: Watchers use almost 30 times as much memory as |
997 | and 10 times as much memory as both Event or EV via AnyEvent. Watcher |
998 | EV watchers, and 10 times as much memory as Event (the high memory |
|
|
999 | requirements are caused by requiring a session for each watcher). Watcher |
998 | invocation is almost 900 times slower than with AnyEvent's pure perl |
1000 | invocation speed is almost 900 times slower than with AnyEvent's pure perl |
999 | implementation. The design of the POE adaptor class in AnyEvent can not |
1001 | implementation. The design of the POE adaptor class in AnyEvent can not |
1000 | really account for this, as session creation overhead is small compared |
1002 | really account for this, as session creation overhead is small compared |
1001 | to execution of the state machine, which is coded pretty optimally within |
1003 | to execution of the state machine, which is coded pretty optimally within |
1002 | L<AnyEvent::Impl::POE>. POE simply seems to be abysmally slow. |
1004 | L<AnyEvent::Impl::POE>. POE simply seems to be abysmally slow. |
1003 | |
1005 | |
1004 | =head2 Summary |
1006 | =head2 Summary |
1005 | |
1007 | |
|
|
1008 | =over 4 |
|
|
1009 | |
1006 | Using EV through AnyEvent is faster than any other event loop, but most |
1010 | =item * Using EV through AnyEvent is faster than any other event loop |
1007 | event loops have acceptable performance with or without AnyEvent. |
1011 | (even when used without AnyEvent), but most event loops have acceptable |
|
|
1012 | performance with or without AnyEvent. |
1008 | |
1013 | |
1009 | The overhead AnyEvent adds is usually much smaller than the overhead of |
1014 | =item * The overhead AnyEvent adds is usually much smaller than the overhead of |
1010 | the actual event loop, only with extremely fast event loops such as the EV |
1015 | the actual event loop, only with extremely fast event loops such as EV |
1011 | adds AnyEvent significant overhead. |
1016 | adds AnyEvent significant overhead. |
1012 | |
1017 | |
1013 | And you should simply avoid POE like the plague if you want performance or |
1018 | =item * You should avoid POE like the plague if you want performance or |
1014 | reasonable memory usage. |
1019 | reasonable memory usage. |
|
|
1020 | |
|
|
1021 | =back |
1015 | |
1022 | |
1016 | |
1023 | |
1017 | =head1 FORK |
1024 | =head1 FORK |
1018 | |
1025 | |
1019 | Most event libraries are not fork-safe. The ones who are usually are |
1026 | Most event libraries are not fork-safe. The ones who are usually are |