asyncio的性能

And*_*rew 10 python python-asyncio

我正在努力熟悉asyncio,所以我决定编写一个数据库客户端.但是,性能与同步代码完全匹配.我确信这是我对一个概念的误解.有人可以解释我在做什么吗?

请参阅以下代码示例:

class Connection:
    def __init__(self, reader, writer, loop):
        self.futures = deque()

        # ...

        self.reader_task = asyncio.async(self.recv_data(), loop=self.loop)

    @asyncio.coroutine
    def recv_data(self):
        while 1:
            try:
                response = yield from self.reader.readexactly(4)
                size, = struct.unpack('I', response)
                response = yield from self.reader.readexactly(size)

                # ...                

                future = self.futures.popleft()

                if not future.cancelled():
                    future.set_result(response)

            except Exception:
                break

    def send_data(self, data):
        future = asyncio.Future(loop=self.loop)
        self.futures.append(future)

        self.writer.write(data)

        return future


loop = asyncio.get_event_loop()


@asyncio.coroutine
def benchmark():
    connection = yield from create_connection(loop=loop, ...)

    for i in range(10000):
        yield from connection.send_data(...)


s = time.monotonic()

loop.run_until_complete(benchmark())

e = time.monotonic()
print('Requests per second:', int(10000 / (e - s)))
Run Code Online (Sandbox Code Playgroud)

提前致谢.

dan*_*ano 12

你在打电话的方式上犯了一个错误send_data.现在,你有这个:

@asyncio.coroutine
def benchmark():
    connection = yield from create_connection(loop=loop, ...)

    for i in range(10000):
        yield from connection.send_data(...)
Run Code Online (Sandbox Code Playgroud)

通过yield from在for循环中使用,在等待下一次调用之前,您正在等待future返回send_data以产生结果.这使您的程序基本同步.您想要拨打所有电话send_data,然后等待结果:

@asyncio.coroutine
def benchmark():
    connection = yield from create_connection(loop=loop, ...)
    yield from asyncio.wait([connection.send_data(..) for _ in range(10000)])
Run Code Online (Sandbox Code Playgroud)

  • @Andrew或多或少,尽管你仍然需要在`benchmark`中添加代码来等待每个`Task`完成.实际上,我相信对`asyncio.wait`的调用会将所有传递给它的coroutine对象转换为内部的`Task`实例. (2认同)