On Fri, Apr 25, 2008 at 11:40:03PM -0400, Uri Guttman <[EMAIL PROTECTED]> wrote: > check out stem's pure perl event loop. there are examples in the
Maybe I'll provide a backend for stem. > modules. it does things in a different direction and doesn't scan > select's bit masks but instead it scans the interesting handles and see > whether their bits are set. it should exhibit good behavior under growth > as all the data are managed in hashes. That is exactly as the anyevent perl backend did in the previous version. I don't see how that should exhibit good behaviour - file descristpors are small integers, so hashes only add overhead over arrays, and checking every file descriptor that way is much slower than scanning the bitmask. Especially in the important case of many handles/few active ones, an approach of "scan all handles" is very slow. (The benchmarks reflect this, you could try with an older anyevent release where we just check the keys of the hash storing fd information: performance is much lower). > ML> I then made a second benchmark, designed not to measure anyevent > overhead, > ML> but to measure real-world performance of a socket server. > > and that /sessions code also shows use of the asyncio module. if you can > benchmark that i would be interested in the results. Hmm, tt seems to have become fashionable lately to call synchronous I/O asynchronous (see IO::Async, another 100% synchronous framework). What exactly is asynchronous about the I/O in that example, it seems to be fully synchronous to me (just event-driven). > ML> For small servers, the overhead introduced by running a lot of perl > ML> opcodes per iteration dominates, however, reflected in the last > benchmark. > > in a heavily loaded server most of the work in in the i/o and should > overwhelm the event loop itself. that is the whole purpose of event > loops as we all know here. I actually don't know that. When I write response data (such as a file in my anime server), the performance of the event loop completely dominates (ignoring IO::AIO overhead in this case, which also of coruse relies on the event loop). Of course, select/poll don't scale at all, unless the majority of handles is active, also not very typical of heavily loaded servers. > ML> However, the net result is that the pure perl event loop performs > ML> better than almost all other event loops (EV being the only exception) > ML> ins erious/medium-sized cases, while I originally expected it to fail > ML> completely w.r.t. performance and being only usable as a workaround when > ML> no "better" event module is installed. > > i don't find that surprising. perl's i/o is decent and as i said above, > a loaded server is doing mostly i/o. Well, since the server in this benchmark hardly does anything, and as you can see by the results, the event loop completely dominates, and bad event loops are a thousand times slower than good ones. When put into requests/s, this means that with POE, you are limited to <1000 requests/s, while with EV you can easily reach hundreds of thousands. Also, this does not explain at all why Event is so slow, and why Glib scales so extremely badly. Most of the stuff that slows down the perl-based event loop is clearly stuff that is much much faster in C. For a reasonable event loop implemented in C, the overhead of calling select should completely dominate the rest of the processing (it does so in EV). This is not the case for any of the event loops I tested with the exception of EV and Event (which "only" has high overhead, but it doesn't grow beyond reason). > i will take a gander and see if i can play with it and add stem's loop > to it. if you want to work on this with me, i wouldn't mind the help. Well, can't say thereis much demand for it, but if you cna give me a pointer on these things in the docs I can probably come up with one before the next release: - how can I do one iteration of the event loop? This is important for condvars: the function must not block after one or more events have been handled. - how do I register a callback to be called when an fh or fd becomes "readable" or "writable"? - how can I register a relative timer? - are there any limitations, for example, what happens when I register two read watchers for one fh (or fd)? - does stem provide something to catch signals synchronously? - how about child status changes or exits? The EV or Event implementation modules should give a good idea of whats required. And for the documentation: - how does stem handle time jumps, if at all? - are it's timers based on absolute or wallclock time or relative/monotonic time? -- The choice of a Deliantra, the free code+content MORPG -----==- _GNU_ http://www.deliantra.net ----==-- _ generation ---==---(_)__ __ ____ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / [EMAIL PROTECTED] -=====/_/_//_/\_,_/ /_/\_\