Skip to content

bpo-44953: Add vectorcall for itemgetter and attrgetter - #27828

Merged
sweeneyde merged 5 commits into
python:mainfrom
sweeneyde:itemgetter_vectorcall
Feb 10, 2022
Merged

bpo-44953: Add vectorcall for itemgetter and attrgetter#27828
sweeneyde merged 5 commits into
python:mainfrom
sweeneyde:itemgetter_vectorcall

Conversation

@sweeneyde

@sweeneydesweeneyde commented Aug 19, 2021

Copy link
Copy Markdown
Member

@sweeneyde

Copy link
Copy Markdown
MemberAuthor

This was inspired by GH-27782, which does the same, and more, for methodcaller.

@sweeneyde

Copy link
Copy Markdown
MemberAuthor

Benchmarks for this change:

itemgetter: Mean +- std dev: [operator_main] 45.3 ns +- 1.3 ns -> [operator_vec] 29.5 ns +- 0.7 ns: 1.54x faster
attrgetter: Mean +- std dev: [operator_main] 61.6 ns +- 1.7 ns -> [operator_vec] 43.8 ns +- 0.9 ns: 1.41x faster

@rhettingerrhettinger added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Aug 20, 2021
@bedevere-bot

Copy link
Copy Markdown

🤖 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.

@bedevere-botbedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Aug 20, 2021
Comment threadModules/_operator.c
Comment threadModules/_operator.c
@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actionsgithub-actionsBot added the stale Stale PR or inactive for long period of time. label Sep 20, 2021
@sweeneyde

Copy link
Copy Markdown
MemberAuthor

The __vectorcalloffset__ behavior was added in GH-20026. I don't think I understand that design decision rather than adding a new PyType_Slot.slot value called something like Py_tp_vectorcall, but it appears to be what we have. The corresponding behavior of __dictoffset__ and __weaklistoffset__ goes back to 2019 in GH-16076. Are there any plans to change these, or is there anything holding this up?

@github-actionsgithub-actionsBot removed the stale Stale PR or inactive for long period of time. label Oct 4, 2021
@sweeneyde

sweeneyde commented Jan 3, 2022

Copy link
Copy Markdown
MemberAuthor

Any plans for this? It may also be relevant to bpo-46148 about optimizing Pathlib.

@sweeneyde

Copy link
Copy Markdown
MemberAuthor

Does anyone with a commit bit want to merge this? This is the kind of callable that's often called in loops.

@sweeneyde

Copy link
Copy Markdown
MemberAuthor

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.

fromoperatorimportitemgetter, attrgetterfromitertoolsimportrepeatfromcollectionsimportnamedtuple, dequefrompyperfimportRunnerclassDefaultClass:
def__init__(self, a, b):
self.a=aself.b=bclassSlotsClass:
__slots__="a", "b"def__init__(self, a, b):
self.a=aself.b=bNamedTuple=namedtuple("NT", ["a", "b"])
MAP_LOOPS=10_000attr_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_classesrunner=Runner()
forclassnameinattr_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,
)
forclassnameinitem_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:

Benchmarkmain_benchPR-27828
tuple-map27.6 ns13.2 ns: 2.09x faster
dict-map39.4 ns24.2 ns: 1.62x faster
NamedTuple-map40.0 ns24.8 ns: 1.61x faster
list-map38.2 ns23.8 ns: 1.61x faster
SlotsClass-map42.8 ns28.1 ns: 1.53x faster
DefaultClass-map45.5 ns31.0 ns: 1.47x faster
tuple-156.7 ns41.4 ns: 1.37x faster
NamedTuple-170.1 ns52.7 ns: 1.33x faster
dict-169.4 ns52.2 ns: 1.33x faster
SlotsClass-175.1 ns56.6 ns: 1.33x faster
list-168.7 ns52.1 ns: 1.32x faster
DefaultClass-176.9 ns59.4 ns: 1.29x faster
Geometric mean(ref)1.48x faster

@sweeneyde
sweeneyde merged commit 0a14506 into python:mainFeb 10, 2022
@sweeneyde
sweeneyde deleted the itemgetter_vectorcall branch February 10, 2022 22:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@sweeneyde@bedevere-bot@methane@rhettinger@markshannon@the-knights-who-say-ni