Repository navigation
Avoid per-class methods in managed wrappers - #91
Merged
Merged
Conversation
`@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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@objcwrappergenerated==andhashmethods for every managed wrapper class, andrelease(each wrapper's finalizer) was specialized per class. Packages with many wrappers paid for both: inserting ~1300 methods into Base's==/hashtables cost Metal.jl about 55 ms of load time, and the first garbage collection of each new class compiledreleasefor it at run time (5-10 ms each).==andhashare now defined once forObject, dispatching on acompare_by_pointer(::Type)trait that the macro sets from itscomparisonoption. Semantics are unchanged: same-class wrappers withcomparison=truecompare by pointer, others go throughobjc_isequal(===by default,isEqual:for NSObjects).releaseand its callees are@nospecialized and precompiled forObject.Effect on Metal.jl, Julia 1.12, M1:
using Metal-40 to -55 ms; no morereleasecompiles in a session.Tests pass locally.