为什么`poll.poll`比`epoll.poll`更快?

时间:2013-12-07 01:24:25

标签: python linux io

我认为epoll应该比poll更快,但是当我进行以下实验时,结果会变慢。

首先,我设置了1个连接了10个客户端套接字的服务器套接字。

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))

然后我使用pollepoll注册了所有客户:

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

最后,我在%timeit中使用IPython来比较运行时:

%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

也许套接字的数量仍然太小而epoll无法击败poll,但我想知道epoll中的内容会在观看的插座数量不足时使其变慢。

1 个答案:

答案 0 :(得分:0)

poll系统调用需要每次都将文件描述符列表复制到内核。这种情况只发生在epoll_ctl上一次,但不是每次调用epoll_wait时都会发生。

此外,对于watched1描述符的数量,epoll_wait是O(1),这意味着无论是等待一个描述符还是等待5,000或50,000个描述符都无关紧要。轮询虽然比选择更有效,但仍然必须每次遍历列表(即,就描述符的数量而言是O(N))。

最后,epoll可以在“边缘触发”模式下工作,除了“正常”模式之外,这意味着内核不需要跟踪你在信号准备就绪后读取了多少数据。这种模式更难掌握,但效率更高。