-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-44953: Add vectorcall for itemgetter and attrgetter #27828
Conversation
This was inspired by GH-27782, which does the same, and more, for methodcaller. |
Benchmarks for this change:
|
🤖 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. |
This PR is stale because it has been open for 30 days with no activity. |
The |
Any plans for this? It may also be relevant to bpo-46148 about optimizing Pathlib. |
Does anyone with a commit bit want to merge this? This is the kind of callable that's often called in loops. |
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:
|
https://bugs.python.org/issue44953