我认为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))
然后我使用poll
和epoll
注册了所有客户:
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
中的内容会在观看的插座数量不足时使其变慢。
答案 0 :(得分:0)
poll系统调用需要每次都将文件描述符列表复制到内核。这种情况只发生在epoll_ctl上一次,但不是每次调用epoll_wait时都会发生。
此外,对于watched1描述符的数量,epoll_wait是O(1),这意味着无论是等待一个描述符还是等待5,000或50,000个描述符都无关紧要。轮询虽然比选择更有效,但仍然必须每次遍历列表(即,就描述符的数量而言是O(N))。
最后,epoll可以在“边缘触发”模式下工作,除了“正常”模式之外,这意味着内核不需要跟踪你在信号准备就绪后读取了多少数据。这种模式更难掌握,但效率更高。