Skip to content

gh-131798: constant fold classmethod and staticmethod in JIT - #148331

Open
kumaraditya303 wants to merge 7 commits into
python:mainfrom
kumaraditya303:jit-classmethod
Open

gh-131798: constant fold classmethod and staticmethod in JIT#148331
kumaraditya303 wants to merge 7 commits into
python:mainfrom
kumaraditya303:jit-classmethod

Conversation

@kumaraditya303

@kumaraditya303kumaraditya303 commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Script used for benchmark:

"""Benchmark for classmethod/staticmethod JIT optimization."""importtimeLOOPS=10_000_000classMyClass:
@classmethoddefclass_method(cls):
returncls@staticmethoddefstatic_method():
return42defregular_method(self):
returnselfobj=MyClass()
defbench_classmethod():
o=objfor_inrange(LOOPS):
o.class_method()
o.class_method()
o.class_method()
o.class_method()
o.class_method()
defbench_staticmethod():
o=objfor_inrange(LOOPS):
o.static_method()
o.static_method()
o.static_method()
o.static_method()
o.static_method()
benchmarks= [
("classmethod", bench_classmethod),
("staticmethod", bench_staticmethod),
]
forname, funcinbenchmarks:
t0=time.perf_counter()
func()
dt=time.perf_counter() -t0print(f"{name:20s}{dt:.3f}s")
BenchmarkmainPRSpeedup
classmethod1.000s0.572s1.75x faster
staticmethod0.860s0.482s1.78x faster

@kumaraditya303

Copy link
Copy Markdown
ContributorAuthor

This can be done for class lookups as well so things like Foo.bar() where bar is a classmethod gets constant folded.

@Fidget-Spinner

Copy link
Copy Markdown
Member

I don't see any change in deltablue, but that's because it's using cls.classmethod() instead of self.classmethod(). Would you like to add that to this PR as well? https://github.com/python/pyperformance/blob/main/pyperformance/data-files/benchmarks/bm_deltablue/run_benchmark.py#L234

@Fidget-Spinner

Copy link
Copy Markdown
Member

I don't see any change in deltablue, but that's because it's using cls.classmethod() instead of self.classmethod(). Would you like to add that to this PR as well? https://github.com/python/pyperformance/blob/main/pyperformance/data-files/benchmarks/bm_deltablue/run_benchmark.py#L234

This turned out to be harder than I thought, because it would fold the classmethod descriptor into a unbound method lookup rather than a bound one, which changes the following CALL_BOUND_METHOD_EXACT_ARGS in the trace.

@NekoAsakura

Copy link
Copy Markdown
Member

The outer else doesn't set self_or_null[0], intentional?

Comment threadPython/optimizer_bytecodes.c Outdated
@markshannon

Copy link
Copy Markdown
Member

I don't see any change in deltablue, but that's because it's using cls.classmethod() instead of self.classmethod(). Would you like to add that to this PR as well? https://github.com/python/pyperformance/blob/main/pyperformance/data-files/benchmarks/bm_deltablue/run_benchmark.py#L234

This turned out to be harder than I thought, because it would fold the classmethod descriptor into a unbound method lookup rather than a bound one, which changes the following CALL_BOUND_METHOD_EXACT_ARGS in the trace.

That shouldn't be a problem for staticmethod though, as self_or_null is always NULL.

It would make sense for LOAD_ATTR 1 for classmethod to be leaving func cls on the stack.

If we special case classmethod in _PyObject_GetMethodStackRef, it should add negligible overhead in the interpreter (possibly speeding things up if classmethods are common) and will enable this optimization in the JIT.

@Fidget-Spinner

Copy link
Copy Markdown
Member

If we special case classmethod in _PyObject_GetMethodStackRef, it should add negligible overhead in the interpreter (possibly speeding things up if classmethods are common) and will enable this optimization in the JIT.

Working on that.

@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 May 18, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core reviewskip newsstaleStale PR or inactive for long period of time.topic-JIT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@kumaraditya303@Fidget-Spinner@NekoAsakura@markshannon