[New-bugs-announce] [issue22127] performance regression in socket.getsockaddr()

Charles-François Natali report at bugs.python.org
Sun Aug 3 10:17:29 CEST 2014


New submission from Charles-François Natali:

I noticed that socket.sendto() got noticably slower since 3.4 (at least), compared to 2.7:

2.7:
$ ./python -m timeit -s "import socket; s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); DATA = b'hello'; TARGET=('127.0.0.1', 4242)" "s.sendto(DATA, TARGET)"
100000 loops, best of 3: 15.8 usec per loop

3.4:
$ ./python -m timeit -s "import socket; s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); DATA = b'hello'; TARGET=('127.0.0.1', 4242)" "s.sendto(DATA, TARGET)"
10000 loops, best of 3: 25.9 usec per loop

A profile reveals this:
2.7:
         100065 function calls in 2.268 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.361    0.361    2.268    2.268 test_send.py:1(<module>)
   100000    1.895    0.000    1.895    0.000 {method 'sendto' of '_socket.socket' objects}


3.4:
         906015 function calls (905975 primitive calls) in 6.132 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      5/1    0.000    0.000    6.132    6.132 {built-in method exec}
        1    0.334    0.334    6.132    6.132 test_send.py:1(<module>)
   100000    2.347    0.000    5.769    0.000 {method 'sendto' of '_socket.socket' objects}
   100000    1.991    0.000    3.411    0.000 idna.py:147(encode)
   500086    0.894    0.000    0.894    0.000 {built-in method len}
   100000    0.269    0.000    0.269    0.000 {method 'encode' of 'str' objects}
   100000    0.257    0.000    0.257    0.000 {method 'split' of 'bytes' objects}


As can be seen, it's the IDNA encoding which takes a long time, and doesn't appear in the 2.7 profile.
The parsing code (including idna codec) is present in both versions though:
"""
static int
getsockaddrarg(PySocketSockObject *s, PyObject *args,
               struct sockaddr *addr_ret, int *len_ret)
[...]
        if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
                              "idna", &host, &port))
            return 0;
"""

I'm currently bisecting the commit, but I'm not familiar with encoding stuff.
Is it expected that the IDNA encoding be called when passed an ascii string?

----------
components: Library (Lib)
messages: 224618
nosy: haypo, loewis, neologix, pitrou
priority: normal
severity: normal
status: open
title: performance regression in socket.getsockaddr()
type: performance
versions: Python 3.4, Python 3.5

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue22127>
_______________________________________


More information about the New-bugs-announce mailing list