{"action":"closed","issue":{"url":"https://api.github.com/repos/ronf/asyncssh/issues/50","repository_url":"https://api.github.com/repos/ronf/asyncssh","labels_url":"https://api.github.com/repos/ronf/asyncssh/issues/50/labels{/name}","comments_url":"https://api.github.com/repos/ronf/asyncssh/issues/50/comments","events_url":"https://api.github.com/repos/ronf/asyncssh/issues/50/events","html_url":"https://github.com/ronf/asyncssh/issues/50","id":135903062,"number":50,"title":"Performance Issues when Forwarding TCP","user":{"login":"theonewolf","id":522248,"avatar_url":"https://avatars.githubusercontent.com/u/522248?v=3","gravatar_id":"","url":"https://api.github.com/users/theonewolf","html_url":"https://github.com/theonewolf","followers_url":"https://api.github.com/users/theonewolf/followers","following_url":"https://api.github.com/users/theonewolf/following{/other_user}","gists_url":"https://api.github.com/users/theonewolf/gists{/gist_id}","starred_url":"https://api.github.com/users/theonewolf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/theonewolf/subscriptions","organizations_url":"https://api.github.com/users/theonewolf/orgs","repos_url":"https://api.github.com/users/theonewolf/repos","events_url":"https://api.github.com/users/theonewolf/events{/privacy}","received_events_url":"https://api.github.com/users/theonewolf/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":16,"created_at":"2016-02-23T23:47:43Z","updated_at":"2016-02-24T03:40:46Z","closed_at":"2016-02-24T03:40:46Z","body":"I'd like to know if anyone knows of performance enhancements we can apply to/with AsyncSSH to boost performance for this use case.\r\n\r\nI am noticing a large amount of overhead when forwarding TCP connections via AsyncSSH vs the OpenSSH client binary.\r\n\r\nFor example, here are some quick timings using OpenSSH on Windows (8.1, OpenSSH_7.0p1, OpenSSL 1.0.2d 9 Jul 2015) and Ubuntu (14.04 LTS, OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6, OpenSSL 1.0.1f 6 Jan 2014); forwarding command similar to `ssh -L 443:localhost:443 ubuntu@something.com`:\r\n\r\n```log\r\n##### Windows OpenSSH Client Binary (-L) #####\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 13.8 msec per loop\r\n\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 18.6 msec per loop\r\n\r\n##### Ubuntu OpenSSH Client Binary (-L) #####\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\");  from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n100 loops, best of 3: 11.1 msec per loop\r\n\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\");  from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n100 loops, best of 3: 11.5 msec per loop\r\n```\r\n\r\nThen I tried using AsyncSSH with basically the following script:\r\n\r\n```python\r\n#!/usr/bin/env python3\r\nfrom asyncio import coroutine, get_event_loop, set_event_loop\r\nfrom sys import exit\r\n\r\nfrom asyncssh import connect, Error\r\n\r\n@coroutine\r\ndef run_client():\r\n    with (yield from connect('something.com', username='ubuntu')) as conn:\r\n        listener = yield from conn.forward_local_port('127.0.0.1', 443, '127.0.0.1', 443)\r\n        yield from listener.wait_closed()\r\n\r\n    yield from conn.wait_closed()\r\n\r\ntry:\r\n    # Windows specific event loop\r\n    #LOOP = ProactorEventLoop()\r\n    #set_event_loop(LOOP)\r\n    get_event_loop().run_until_complete(run_client())\r\nexcept (OSError, Error) as exc:\r\n    exit('SSH connection failed: ' + str(exc))\r\n```\r\n\r\nWhat I found on Windows:\r\n\r\n```log\r\n##### Windows AsyncSSH (develop branch) TCP Forwarder with Proactor Event Loop #####\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 229 msec per loop\r\n\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 213 msec per loop\r\n\r\n\r\n##### Windows AsyncSSH (develop branch) TCP Forwarder with Default Event Loop #####\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 228 msec per loop\r\n\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\"); from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 226 msec per loop\r\n```\r\n\r\nand what I found on Ubuntu (practically the same overhead):\r\n\r\n```log\r\n##### Ubuntu AsyncSSH (develop branch) TCP Forwarder with Default Event Loop #####\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\");  from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 201 msec per loop\r\n\r\n$ python -mtimeit -s 'from warnings import filterwarnings; filterwarnings(\"ignore\");  from requests import Session; s = Session()' 's.get(\"https://127.0.0.1\", verify=False)'\r\n10 loops, best of 3: 206 msec per loop\r\n```"}}