[Python-checkins] gh-91487: Optimize asyncio UDP speed (GH-91488)
miss-islington
webhook-mailer at python.org
Fri Apr 15 15:59:11 EDT 2022
https://github.com/python/cpython/commit/42fabc3ea767f10989363536eaaa9da32616ab57
commit: 42fabc3ea767f10989363536eaaa9da32616ab57
branch: main
author: msoxzw <56633971+msoxzw at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022年04月15日T12:59:01-07:00
summary:
gh-91487: Optimize asyncio UDP speed (GH-91488)
Fix #91487
When transferring a small file, e.g. 256 KiB, the speed of this PR is comparable. However, if a large file, e.g. 65536 KiB, is transferred, asyncio UDP will be over 100 times faster than the original. The speed is presumably significantly faster if a larger file is transferred, e.g. 1048576 KiB.
Automerge-Triggered-By: GH:gpshead
files:
A Misc/NEWS.d/next/Library/2022-04-15-19-34-02.gh-issue-91487.2aqguF.rst
M Lib/asyncio/proactor_events.py
M Lib/asyncio/selector_events.py
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index ff6d08f78eecb..9636c6b4d28fa 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -459,6 +459,7 @@ def __init__(self, loop, sock, protocol, address=None,
waiter=None, extra=None):
self._address = address
self._empty_waiter = None
+ self._buffer_size = 0
# We don't need to call _protocol.connection_made() since our base
# constructor does it for us.
super().__init__(loop, sock, protocol, waiter=waiter, extra=extra)
@@ -471,7 +472,7 @@ def _set_extra(self, sock):
_set_socket_extra(self, sock)
def get_write_buffer_size(self):
- return sum(len(data) for data, _ in self._buffer)
+ return self._buffer_size
def abort(self):
self._force_close(None)
@@ -496,6 +497,7 @@ def sendto(self, data, addr=None):
# Ensure that what we buffer is immutable.
self._buffer.append((bytes(data), addr))
+ self._buffer_size += len(data)
if self._write_fut is None:
# No current write operations are active, kick one off
@@ -522,6 +524,7 @@ def _loop_writing(self, fut=None):
return
data, addr = self._buffer.popleft()
+ self._buffer_size -= len(data)
if self._address is not None:
self._write_fut = self._loop._proactor.send(self._sock,
data)
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index e99a50395e7cb..c9bbe2ac01435 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -1131,6 +1131,7 @@ def __init__(self, loop, sock, protocol, address=None,
waiter=None, extra=None):
super().__init__(loop, sock, protocol, extra)
self._address = address
+ self._buffer_size = 0
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
self._loop.call_soon(self._add_reader,
@@ -1141,7 +1142,7 @@ def __init__(self, loop, sock, protocol, address=None,
waiter, None)
def get_write_buffer_size(self):
- return sum(len(data) for data, _ in self._buffer)
+ return self._buffer_size
def _read_ready(self):
if self._conn_lost:
@@ -1200,11 +1201,13 @@ def sendto(self, data, addr=None):
# Ensure that what we buffer is immutable.
self._buffer.append((bytes(data), addr))
+ self._buffer_size += len(data)
self._maybe_pause_protocol()
def _sendto_ready(self):
while self._buffer:
data, addr = self._buffer.popleft()
+ self._buffer_size -= len(data)
try:
if self._extra['peername']:
self._sock.send(data)
@@ -1212,6 +1215,7 @@ def _sendto_ready(self):
self._sock.sendto(data, addr)
except (BlockingIOError, InterruptedError):
self._buffer.appendleft((data, addr)) # Try again later.
+ self._buffer_size += len(data)
break
except OSError as exc:
self._protocol.error_received(exc)
diff --git a/Misc/NEWS.d/next/Library/2022-04-15-19-34-02.gh-issue-91487.2aqguF.rst b/Misc/NEWS.d/next/Library/2022-04-15-19-34-02.gh-issue-91487.2aqguF.rst
new file mode 100644
index 0000000000000..d3c41a7e4cbc1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-04-15-19-34-02.gh-issue-91487.2aqguF.rst
@@ -0,0 +1 @@
+Optimize asyncio UDP speed, over 100 times faster when transferring a large file.
More information about the Python-checkins
mailing list