Ruby: restrict join order of API graph predicates#12804
Conversation
|
You might get better predictability of joins by using |
|
@aschackmull I used
|
|
@kaspersv FYI ^ |
4bdd756 to
69cb138
Compare
hvitved
left a comment
There was a problem hiding this comment.
LGTM, just a couple of questions.
| // Class methods | ||
| API::getTopLevelMember("ActiveStorage") | ||
| .getMember("Blob") | ||
| .getASubclass() |
There was a problem hiding this comment.
From the PR description:
The PR also removes some uses of getASubclass() which were redundant because it came before a member predicate that itself performs getASubclass(). The optimizer did not handle that very well.
| ServiceInstantiation() { | ||
| this = | ||
| API::getTopLevelMember("Twirp").getMember("Service").getASubclass().getAnInstantiation() | ||
| this = API::getTopLevelMember("Twirp").getMember("Service").getAnInstantiation() |
There was a problem hiding this comment.
Here getASubclass has been removed, because asking for getAnInstantiation will include instantiations of sub classes?
There was a problem hiding this comment.
Yes, again, from the PR description:
The PR also removes some uses of getASubclass() which were redundant because it came before a member predicate that itself performs getASubclass(). The optimizer did not handle that very well.
| * Same as `getMember` but without join-order hints. | ||
| */ | ||
| cached | ||
| Node getMemberInternal(string m) { |
There was a problem hiding this comment.
I would prefer to have such internal predicates be either top-level predicates or on a an internal Impl class.
There was a problem hiding this comment.
Moved to an internal class at API::Node::Internal.
Places join-order restrictions on API graphs to more reliably get a good join order at the use-sites. This is done by caching more predicates, and placing inline facade predicates in front to enforce a good join ordering at the call site.
While working on adding better support for instance members in API graphs, I noticed the join order in some library models would go haywire seemingly at random, and this PR is meant to stop that from happening.
To explain, a chain of API-graph calls should be evaluated from left to right. For example,
Should be evaluated by first finding uses of
Barand then calls tobazon those objects.But sometimes it gets evaluated backwards, by starting at calls to
bazand then checking if their receiver isBar(it's more complex than that, but that's the basic idea). In this small example it's not so bad, but in practice backwards evaluation is really bad. Previously this was left mostly to the optimizer to figure out, which it very often did, but not always.The PR also removes some uses of
getASubclass()which were redundant because it came before a member predicate that itself performsgetASubclass(). The optimizer did not handle that very well.Evaluation shows an average speed-up of about 2%.