bpo-44953: Add vectorcall for itemgetter and attrgetter#27828
Conversation
|
This was inspired by GH-27782, which does the same, and more, for methodcaller. |
Sorry, something went wrong.
|
Benchmarks for this change: |
Sorry, something went wrong.
|
🤖 New build scheduled with the buildbot fleet by @rhettinger for commit f9fc83a 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
Sorry, something went wrong.
|
This PR is stale because it has been open for 30 days with no activity. |
Sorry, something went wrong.
|
The |
Sorry, something went wrong.
|
Any plans for this? It may also be relevant to bpo-46148 about optimizing Pathlib. |
Sorry, something went wrong.
|
Does anyone with a commit bit want to merge this? This is the kind of callable that's often called in loops. |
Sorry, something went wrong.
|
I re-ran some benchmarks, and they still look good. I plan to merge this in about 24 hours if there are no more objections. from operator import itemgetter, attrgetter
from itertools import repeat
from collections import namedtuple, deque
from pyperf import Runner
class DefaultClass:
def __init__(self, a, b):
self.a = a
self.b = b
class SlotsClass:
__slots__ = "a", "b"
def __init__(self, a, b):
self.a = a
self.b = b
NamedTuple = namedtuple("NT", ["a", "b"])
MAP_LOOPS = 10_000
attr_classes = {
'DefaultClass': DefaultClass,
'SlotsClass': SlotsClass,
'NamedTuple': NamedTuple,
}
item_classes = {
'tuple': tuple,
'list': list,
'dict': dict.fromkeys,
}
namespace = {
'IG': itemgetter(1),
'AG': attrgetter('a'),
'repeat': repeat,
'deque': deque,
} | attr_classes | item_classes
runner = Runner()
for classname in attr_classes:
runner.timeit(
name=f"{classname}-1",
setup=f"obj = {classname}(11, 22)",
stmt="AG(obj)",
globals=namespace
)
runner.timeit(
name=f"{classname}-map",
setup=f"obj = {classname}(11, 22)",
stmt=f"deque(map(AG, repeat(obj, {MAP_LOOPS})), maxlen=0)",
globals=namespace,
inner_loops=MAP_LOOPS,
)
for classname in item_classes:
runner.timeit(
name=f"{classname}-1",
setup=f"obj = {classname}((1, 2, 3, 4, 5))",
stmt="IG(obj)",
globals=namespace,
)
runner.timeit(
name=f"{classname}-map",
setup=f"obj = {classname}((1, 2, 3, 4, 5))",
stmt=f"deque(map(IG, repeat(obj, {MAP_LOOPS})), maxlen=0)",
globals=namespace,
inner_loops=MAP_LOOPS,
)Results:
|
Sorry, something went wrong.
https://bugs.python.org/issue44953