Skip to content

Instantly share code, notes, and snippets.

@KostyaEsmukov
Last active April 11, 2024 06:30
Show Gist options
  • Save KostyaEsmukov/2404d862e786153994d20730aaf13045 to your computer and use it in GitHub Desktop.
Save KostyaEsmukov/2404d862e786153994d20730aaf13045 to your computer and use it in GitHub Desktop.
go vs py3 asyncio vs node vs socat - tcp piping performance
iperf -s -p 5201 -V
iperf -c ::1 -p 5202 -t 10 -d --format Mbits -V
iperf3 -s
iperf3 -c ::1 -p 5202 -i 1 -t 10
socat tcp6-listen:5202 tcp6-connect:'[::1]:5201'
https://github.com/BlueDragonX/go-proxy-example
./go-proxy-example -listen='[::1]:5202' -backend='[::1]:5201'
directly
8320 MBytes 832 MBytes/sec
nodejs (also tried raising HWM and tuning GC - all the same)
2554 MBytes 255 MBytes/sec
cpython3.5 asyncio protocol (also tried raising write buffer limit + tuning GC limits - all the same)
4382 MBytes 438 MBytes/sec
pypy3 asyncio protocol
3635 MBytes 363 MBytes/sec
cpython 3.5 asyncio protocol + uvloop
3005 MBytes 300 MBytes/sec
go
3271 MBytes 327 MBytes/sec
socat default
2813 MBytes 281 MBytes/sec
socat with buffer 2^16
8904 MBytes 890 MBytes/sec
var net = require('net');
var server = net.createServer(function(socket) {
console.log('acc');
var client = new net.Socket();
client.connect(5201, '::1', function() {
socket.pipe(client);
client.pipe(socket);
});
});
server.listen(5202, '::1');
import asyncio
from time import sleep
class ClientProtocol(asyncio.Protocol):
transport = None
def __init__(self, server_transport):
self.server_transport = server_transport
self.write_q = []
def connection_made(self, transport):
self.transport = transport
self.server_transport.resume_reading()
print('resume')
while self.write_q:
self.transport.write(self.write_q.pop(0))
def data_received(self, data):
self.server_transport.write(data)
def write(self, data):
if self.transport is None:
self.write_q.append(data)
return
self.transport.write(data)
class ServerProtocol(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
self.transport.pause_reading()
print('pause')
self.client_protocol = ClientProtocol(self.transport)
coro = loop.create_connection(lambda: self.client_protocol, '::1', 5201)
loop.create_task(coro)
def data_received(self, data):
self.client_protocol.write(data)
loop = asyncio.get_event_loop()
coro = loop.create_server(ServerProtocol, '::1', 5202)
server = loop.run_until_complete(coro)
loop.run_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment