Created
April 12, 2022 23:10
-
-
Save msoxzw/8ae5c488edbc2985d41563c4d9c9cc04 to your computer and use it in GitHub Desktop.
asycnio udp benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import asyncio | |
import struct | |
_I = struct.Struct('!I') | |
class UDPClient(asyncio.DatagramProtocol): | |
def __init__(self, size, time): | |
self.loop = asyncio.get_running_loop() | |
self.size = size | |
self.time = time | |
def datagram_received(self, data, addr): | |
self.size -= len(data) | |
if not self.size: | |
self.time.set_result(self.loop.time()) | |
class UDPServer(asyncio.DatagramProtocol): | |
def __init__(self, packet): | |
self.packet = packet | |
self.transport = None | |
def connection_made(self, transport): | |
self.transport = transport | |
def datagram_received(self, data, addr): | |
count, = _I.unpack(data) | |
for _ in range(count): | |
self.transport.sendto(self.packet, addr) | |
async def benchmark(count=65535, packet_size=1024, host='127.0.0.1', port=9999): | |
loop = asyncio.get_running_loop() | |
finish_time = loop.create_future() | |
size = count * packet_size | |
server, _ = await loop.create_datagram_endpoint( | |
lambda: UDPServer(bytes(packet_size)), | |
local_addr=(host, port), | |
) | |
client, _ = await loop.create_datagram_endpoint( | |
lambda: UDPClient(size, finish_time), | |
remote_addr=(host, port), | |
) | |
client.sendto(_I.pack(count), (host, port)) | |
start_time = loop.time() | |
try: | |
print('Transfer speed: {:.3f} Mbps'.format( | |
size * 8 / 1000 / 1000 / (await finish_time - start_time))) | |
finally: | |
client.close() | |
server.close() | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('count', type=int, nargs='?', default=65536) | |
args = parser.parse_args() | |
asyncio.run(benchmark(args.count)) |
A quick Wireshark session shows that all the packets leave the "server side", but only 93 (in case of 1024-bytes) packets ever reach the "client side". Decreasing the size of the packet to 512 increases the number of received packets to 167. Or 4 packets of 64000 bytes. So, seems like receive buffer problem.
Thank you for investigating this issue. Similarly, I believe that the UDP packets are dropped by the OS, which pertains to [the UDP receive buffer](https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size), but Python per se should tackle this situation.
…________________________________
From: Vadim Bulavintsev ***@***.***>
Sent: Wednesday, November 2, 2022 11:21 PM
To: ichorid ***@***.***>
Cc: Author ***@***.***>; Comment ***@***.***>
Subject: Re: msoxzw/udp.py
@ichorid commented on this gist.
________________________________
A quick Wireshark session shows that all the packets leave the "server side", but only 93 (in case of 1024-bytes) packets ever reach the "client side". Decreasing the size of the packet to 512 increases the number of received packets to 167. Or 4 packets of 64000 bytes. So, seems like receive buffer problem.
—
Reply to this email directly, view it on GitHub<https://gist.github.com/8ae5c488edbc2985d41563c4d9c9cc04#gistcomment-4356507> or unsubscribe<https://github.com/notifications/unsubscribe-auth/ANQCU44I7WHTWQERZQF5WPTWGLZRLBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVEYTCNJXGMZTCNRVU52HE2LHM5SXFJTDOJSWC5DF>.
You are receiving this email because you authored a thread.
Triage notifications on the go with GitHub Mobile for iOS<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> or Android<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When I stop it with the debugger, it is always stuck in
EpollSelector._selector.poll(timeout, max_ev)
. Either this behaviour results from differences between socket usage semantics of Windows and Linux, or there is a horrible bug in SelectorLoop implementation.