-
Notifications
You must be signed in to change notification settings - Fork 656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable key fields check if unnecessary and optimize its perf #3720
Conversation
/** | ||
* Returns whether the `typePolicy` directive is present on at least one object in the schema | ||
*/ | ||
fun hasAnyTypePolicyDirectives(): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: rename to hasTypeWithTypePolicy
?
|
||
private val keyFieldsCache = mutableMapOf<String, Set<String>>() | ||
fun keyFields(name: String) = keyFieldsCache.getOrPut(name) { | ||
schema.keyFields(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
parentType: String, | ||
implementedTypes: Set<String>, | ||
) = collectFieldsCache.getOrPut("$selections $parentType $implementedTypes") { | ||
collectFields(selections, parentType, implementedTypes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any idea the cache hit ratio for this? I'd expect it to be relatively low?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the test in the PR I can see that the method was run 2693
times overall, and only 405
times after making it cached. So 2288
duplicated calls, meaning ~80% cache hit?
checkKeyFields(it, options.schema, allFragmentDefinitions) | ||
// Check if all the key fields are present in operations and fragments | ||
// (do this only if there are key fields as it may be costly) | ||
if (options.schema.hasAnyTypePolicyDirectives()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
import kotlin.time.measureTime | ||
|
||
@OptIn(ExperimentalTime::class, ApolloExperimental::class) | ||
class PerfTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do everything from CodegenTest
? CodegenTest
writes a measurements
file containing the codegen time IIRC so it might be enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I really don't think we should push that test and indeed it should be one of the regular tests ran by CodegenTest
(in fact it already does because where the files are located, and fails because I didn't generate the .expected 😅). But since it's fairly slow, and we may want to continue investigations, it's easier to have a dedicated test temporarily. If we want to merge this branch, let's remove or move it first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to merge the other fixes quickly. My moving the test to another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 let's do it!
6007e4b
to
8eaa0d6
Compare
* Returns whether the `typePolicy` directive is present on at least one object in the schema | ||
*/ | ||
fun hasTypeWithTypePolicy(): Boolean { | ||
return typeDefinitions.values.filterIsInstance<GQLObjectTypeDefinition>().any { objectType -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for our future selves: we'll want to support @typePolicy
on interfaces and unions (see #3356). This will need to be updated when this happens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
This branch investigates a performance issue in the compiler around check key fields, that has been reported.
typePolicy
directivesimplementedTypes
andkeyFields
collectFields
entirely👆 when profiling, these changes seem to show the check runs faster, however we still don't have a convincing repro steps where it was taking a significant time overall, so caution must be taken