Why is `poll.poll` faster than `epoll.poll`?
Question: I thought `epoll` should be faster than `poll`, but when I do the following
experiment, it turns out to be slower.

First I set up 1 server socket with 10 client sockets connected.

    
    
    import socket
    server = socket.socket()
    server.bind(('127.0.0.1', 7777))
    server.listen(1)
    
    clients = [socket.socket() for i in range(10)]
    for c in clients:
        c.connect(('127.0.0.1', 7777))
    

Then I registered all clients with both `poll` and `epoll`:

    
    
    import select
    ep = select.epoll()
    p = select.poll()
    for c in clients:
        p.register(c)
        ep.register(c)
    

Finally I use `%timeit` in `IPython` to compare the runtime:

    
    
    %timeit p.poll()
    1000000 loops, best of 3: 1.26 us per loop
    %timeit ep.poll()
    1000000 loops, best of 3: 1.7 us per loop
    

Maybe the number of sockets are still too small for `epoll` to beat `poll`,
but I wonder what's in `epoll` that make it slower when there are not many
sockets watched.


Answer: The poll system call needs to copy your list of file descriptors to the kernel
each time. This happens only once with epoll_ctl, but not every time you call
epoll_wait.

Also, epoll_wait is O(1) in respect of the number of descriptors watched1,
which means it does not matter whether you wait on one descriptor or on 5,000
or 50,000 descriptors. poll, while being more efficient than select, still has
to walk over the list every time (i.e. it is O(N) in respect of number of
descriptors).

And lastly, epoll can in addition to the "normal" mode work in "edge
triggered" mode, which means the kernel does not need keep track of how much
data you've read after you've been signalled readiness. This mode is more
difficult to grasp, but somewhat more efficient.

