Skip to content

Conversation

@sweeneyde
Copy link
Member

@sweeneydesweeneyde commented Aug 19, 2021

@sweeneyde
Copy link
MemberAuthor

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

@sweeneyde
Copy link
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

🤖 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
@github-actions
Copy link

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
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
Copy link
MemberAuthor

sweeneyde commented Jan 3, 2022

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

@sweeneyde
Copy link
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
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

@sweeneydesweeneyde merged commit 0a14506 into python:mainFeb 10, 2022
@sweeneydesweeneyde 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