Skip to content

Avoid per-class methods in managed wrappers - #91

Merged
maleadt merged 2 commits into
mainfrom
tb/loadtime
Oct 20, 2026
Merged

maleadt merged 2 commits into
mainfrom
tb/loadtime

Conversation

@maleadt

@maleadt maleadt commented Oct 20, 2026

Copy link
Copy Markdown
Member

@objcwrapper generated == and hash methods for every managed wrapper class, and release (each wrapper's finalizer) was specialized per class. Packages with many wrappers paid for both: inserting ~1300 methods into Base's ==/hash tables cost Metal.jl about 55 ms of load time, and the first garbage collection of each new class compiled release for it at run time (5-10 ms each).

  • == and hash are now defined once for Object, dispatching on a compare_by_pointer(::Type) trait that the macro sets from its comparison option. Semantics are unchanged: same-class wrappers with comparison=true compare by pointer, others go through objc_isequal (=== by default, isEqual: for NSObjects).
  • release and its callees are @nospecialized and precompiled for Object.

Effect on Metal.jl, Julia 1.12, M1: using Metal -40 to -55 ms; no more release compiles in a session.

Tests pass locally.

`@objcwrapper` defined `==` and `hash` methods for every managed wrapper class.
Inserting a method into large Base method tables is expensive at load time,
and for Metal.jl's ~660 wrappers these methods cost about 55 ms of its load
time. Instead, record the `comparison` option as a `compare_by_pointer` trait
and implement `==` and `hash` once for all objects. The `isEqual:` fallback
for NSObjects moves to `objc_isequal`, keeping the existing semantics.
`release` is the finalizer of every managed wrapper, so the first time the
garbage collector frees an object of a new class it compiled `release` and
its callees for that class, at run time (5-10 ms each). Compile a single
unspecialized version instead, and precompile it.
@maleadt
maleadt merged commit c56ee83 into main Oct 20, 2026
12 checks passed
@maleadt
maleadt deleted the tb/loadtime branch October 20, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant