bpo-32492: 1.6x speed up in namedtuple attribute access using C fast-path by pablogsal · Pull Request #10495 · python/cpython (original) (raw)

Timing benchmarks

Attribute Access

import perf

runner = perf.Runner() runner.timeit("a.x", stmt="a.x", setup="import collections;A=collections.namedtuple('A','x')")

./python -m perf compare_to old.json new.json -v
Mean +- std dev: [old] 280 ns +- 3 ns -> [new] 111 ns +- 1 ns: 2.52x faster

Apparently, there is a regression in the current master. This is the comparison against 3.7:

Mean +- std dev: [old] 176 ns +- 2 ns -> [new] 110 ns +- 2 ns: 1.61x faster (-38%)
Significant (t=177.69)

Creation

(Just to check that creation is not slower)

import perf

runner = perf.Runner() runner.timeit("collections.namedtuple('A','x')", stmt="collections.namedtuple('A','x')", setup="import collections")

Mean +- std dev: [old_creation] 209 us +- 3 us -> [new_creation] 207 us +- 4 us: 1.01x faster

import perf

runner = perf.Runner() runner.timeit("A(2324)", stmt="A(2324)", setup="import collections;A=collections.namedtuple('A','x')")

Mean +- std dev: [old_creation_obj] 1.41 us +- 0.03 us -> [new_creation_obj] 1.41 us +- 0.02 us: 1.00x faster (-0%)

Cache efficiency

Baseline

❯ perf stat -r 200 -B -e cache-references,cache-misses,cycles,instructions,branches,faults,migrations ./python -c "
import collections
A = collections.namedtuple('A','x');a = A(42)
for _ in range(100):
    some_var = a.x
"""


 Performance counter stats for './python -c
import collections
A = collections.namedtuple('A','x');a = A(42)
for _ in range(100):
    some_var = a.x
' (200 runs):

         1,469,290      cache-references:u                                            ( +-  0.26% )
            20,240      cache-misses:u            #    1.378 % of all cache refs      ( +-  8.58% )
       146,812,273      cycles:u                                                      ( +-  0.24% )
       201,131,089      instructions:u            #    1.37  insn per cycle           ( +-  0.01% )
        40,257,360      branches:u                                                    ( +-  0.01% )
             1,175      faults:u                                                      ( +-  0.01% )
                 0      migrations:u

          0.050526 +- 0.000281 seconds time elapsed  ( +-  0.56% )

Patched

❯ perf stat -r 200 -B -e cache-references,cache-misses,cycles,instructions,branches,faults,migrations ./python -c "
import collections
A = collections.namedtuple('A','x');a = A(42)
for _ in range(100):
    some_var = a.x
"""                                

 Performance counter stats for './python -c
import collections
A = collections.namedtuple('A','x');a = A(42)
for _ in range(100):
    some_var = a.x
' (200 runs):

         1,471,736      cache-references:u                                            ( +-  0.11% )
             7,196      cache-misses:u            #    0.489 % of all cache refs      ( +-  6.94% )
       145,004,120      cycles:u                                                      ( +-  0.07% )
       201,182,075      instructions:u            #    1.39  insn per cycle           ( +-  0.01% )
        40,219,107      branches:u                                                    ( +-  0.01% )
             1,174      faults:u                                                      ( +-  0.01% )
                 0      migrations:u

          0.048499 +- 0.000222 seconds time elapsed  ( +-  0.44% )

https://bugs.python.org/issue32492