On Mon, Dec 14, 2020 at 9:11 AM Paul Sokolovsky <pmis...@gmail.com> wrote:
> What would be the explanation for all that?
>
>
> For reference, the disassembly of the 3 lines with CPython3.7 is
> provided:
>
>   1           0 LOAD_NAME                0 (obj)
>               2 LOAD_METHOD              1 (meth)
>               4 CALL_METHOD              0
>               6 POP_TOP
>
>   2           8 LOAD_NAME                0 (obj)
>              10 LOAD_METHOD              1 (meth)
>              12 CALL_METHOD              0
>              14 POP_TOP
>
>   3          16 LOAD_NAME                0 (obj)
>              18 LOAD_ATTR                1 (meth)
>              20 STORE_NAME               2 (t)
>              22 LOAD_NAME                2 (t)
>              24 CALL_FUNCTION            0
>              26 POP_TOP
> ...

Creating bound method objects can be expensive. Python has a history
of noticing ways to improve performance without changing semantics,
and implementing them. Details here:

https://docs.python.org/3/library/dis.html#opcode-LOAD_METHOD

If you force the bound method object to be created (by putting it in a
variable), the semantics should be the same, but performance will be
lower. Consider:

rosuav@sikorsky:~$ python3.10 -c 'import dis; dis.dis(lambda obj:
(obj.meth,)[0]())'
  1           0 LOAD_FAST                0 (obj)
              2 LOAD_ATTR                0 (meth)
              4 BUILD_TUPLE              1
              6 LOAD_CONST               1 (0)
              8 BINARY_SUBSCR
             10 CALL_FUNCTION            0
             12 RETURN_VALUE
rosuav@sikorsky:~$ python3.10 -c 'import dis; dis.dis(lambda obj:
(obj.meth(),)[0])'
  1           0 LOAD_FAST                0 (obj)
              2 LOAD_METHOD              0 (meth)
              4 CALL_METHOD              0
              6 BUILD_TUPLE              1
              8 LOAD_CONST               1 (0)
             10 BINARY_SUBSCR
             12 RETURN_VALUE

rosuav@sikorsky:~$ python3.10 -m timeit -s 'x, f = 142857, lambda obj:
(obj.bit_length(),)[0]' 'f(x)'
2000000 loops, best of 5: 101 nsec per loop
rosuav@sikorsky:~$ python3.10 -m timeit -s 'x, f = 142857, lambda obj:
(obj.bit_length,)[0]()' 'f(x)'
2000000 loops, best of 5: 124 nsec per loop

rosuav@sikorsky:~$ python3.6 -m timeit -s 'x, f = 142857, lambda obj:
(obj.bit_length(),)[0]' 'f(x)'
10000000 loops, best of 3: 0.124 usec per loop
rosuav@sikorsky:~$ python3.6 -m timeit -s 'x, f = 142857, lambda obj:
(obj.bit_length,)[0]()' 'f(x)'
10000000 loops, best of 3: 0.123 usec per loop

Measurable improvement in 3.10, indistinguishable in 3.6.

This is why lots of us are unimpressed by your strict mode - CPython
is perfectly capable of optimizing the common cases without changing
the semantics, so why change the semantics? :)

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/5KBT5DI6NKKLS4QEDAYNIHKOFBGL7PFP/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to