bpo-28638: speed up namedtuple creation by avoiding exec by JelleZijlstra · Pull Request #2736 · python/cpython

@JelleZijlstra

Creating a namedtuple is relatively slow because it uses exec().
This commit reduces the exec()'ed code, but still uses exec() for
creating the __new__ method. I don't know of a way to avoid using
exec() for __new__ beyond manipulating bytecode directly.

However, avoiding exec() for creating the class itself still yields
a significant speedup. In an unscientific benchmark I ran, creating
1000 namedtuple classes now takes about 0.14 s instead of 0.44 s.

There is one backward compatibility break: namedtuples no longer have
a _source attribute, because we no longer exec() their source. I kept
the verbose=True argument around for compatibility, but it now does
nothing.

ilevkivskyi

ilevkivskyi

methane

pitrou

serhiy-storchaka

JelleZijlstra added a commit to JelleZijlstra/cnamedtuple that referenced this pull request

Jul 19, 2017
Notes:
- fasternt.py is a copy of collections/__init__.py as of python/cpython#2736
- you need to install perf==0.9.6 to run the benchmark, the latest version doesn't work
- run the benchmark with ./bench in the prof directory.

In summary, fasternt is ~4x faster than the stdlib at creating namedtuple classes and has no
effect on instantiation or attribute access. cnamedtuple is 40x faster at class creation
and ~30% faster at instantiation and attribute access.

methane

@JelleZijlstra

@JelleZijlstra

eric-wieser

eric-wieser

eric-wieser

eric-wieser

emmatyping