stored method interference graph (#58948)
Store full method interference relationship graph in interferences field
of Method to avoid expensive morespecific calls during dispatch. This
provides significant performance improvements:
- Replace method comparisons with precomputed interference lookup.
- Optimize ml_matches minmax computation using interference lookups.
- Optimize sort_mlmatches for large return sets by iterating over
interferences instead of all matching methods.
- Add method_morespecific_via_interferences in both C and Julia.
This representation may exclude some edges that are implied by
transitivity since sort_mlmatches will ensure the correct result by
following strong edges. Ambiguous edges are guaranteed to be checkable
without recursion.
Also fix a variety of bugs along the way:
- Builtins signature would cause them to try to discard all other
methods during `sort_mlmatches`.
- Some ambiguities were over-estimated, which now are improved upon.
- Setting lim==-1 now gives the same limited list of methods as lim>0,
since that is actually faster now than attempting to give the
unsorted list. This provides a better fix to #53814 than #57837 and
fixes #58766.
- Reverts recent METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC attempt (though
not the whole commit), since I found a significant problem with any
usage of that bit during testing: it only tracks methods that
intersect with a target, but new methods do not necessarily intersect
with any existing target.
This provides a decent performance improvement to `methods` calls, which
implies a decent speed up to package loading also (e.g. ModelingToolkit
loads in about 4 seconds instead of 5 seconds).