SSLSocket.sendall is much much slower than CPython for large messages
SSLSocket.sendall is much, much slower than CPython for large messages. See the attached repro: repro-pypy-slow-ssl-send.py
To run the repro download the client/server/ca.pem files to the same directory as repro-pypy-slow-ssl-send.py:
Then run the script. With CPython 3.10:
time python3.10 repro-pypy-slow-ssl-send.py
3.10.0 (v3.10.0:b494f5935c, Oct 4 2021, 14:59:20) [Clang 12.0.5 (clang-1205.0.22.11)]
Sendall: 47185920 bytes
Done sending
Done reading
python3.10 repro-pypy-slow-ssl-send.py 0.11s user 0.08s system 105% cpu 0.178 total
With PyPy 3.7
3.7.9 (7e6e2bb30ac5fbdbd443619cae28c51d5c162a02, Dec 30 2020, 17:59:49)
[PyPy 7.3.3-beta0 with GCC Apple LLVM 12.0.0 (clang-1200.0.32.28)]
Sendall: 47185920 bytes
Done sending
Done reading
pypy3.7 repro-pypy-slow-ssl-send.py 6.67s user 1.86s system 102% cpu 8.288 total
You can see that sending a ~45MB message using sendall is 46 times slower in PyPy vs CPython. Note that attempting to chunk the data to sendall yields slightly better performance but it is still much slower than CPython:
# Chunking the data to send improves performance on PyPy but is
# still much slower than CPython.
CHUNK_SIZE = 16384
def sendallchunked(sock, msg):
view = memoryview(msg)
while view:
sock.sendall(view[:CHUNK_SIZE])
view = view[CHUNK_SIZE:]