我想熟悉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)))
感謝。
完美,謝謝。從我可以理解的每一個「send_data」調用創建一個任務相同? – Andrew 2015-02-06 19:23:46
@Andrew或多或少,雖然你仍然需要添加代碼到'benchmark'來等待每個'Task'完成。實際上,我認爲調用'asyncio.wait'會將所有傳遞給它的協程對象內部轉換爲'Task'實例。 – dano 2015-02-06 19:40:41
是的,你們都是對的。 'asyncio.wait'將包裝任何傳入協程對象或在未來的任務中等待。使用'loop.create_task'或'asyncio.ensure_future'自己封裝它們的行爲可能會在循環中安排它們,但在最終完成時不阻止執行協程代碼。你仍然必須從那些Task中產生出來,或者把它們傳遞給'asyncio.wait'。 – 2016-10-01 06:07:19