Skip to content

Some benchmarking and improvements to schema creation times and object allocations#2453

Merged
bbakerman merged 8 commits into
masterfrom
schema_benachmarking
Jul 18, 2021
Merged

Some benchmarking and improvements to schema creation times and object allocations#2453
bbakerman merged 8 commits into
masterfrom
schema_benachmarking

Conversation

@bbakerman

Copy link
Copy Markdown
Member

I started by running things under JProfiler

I noticed some hotspots and then decided to have a look at them

I added benchmark to ensure I got progress

Starting Benchmark

Benchmark                                    Mode  Cnt   Score   Error  Units
SchemaBenchMark.benchMarkLargeSchemaCreate  thrpt   15  16.243 ± 2.037  ops/s

I then applied the Immutable list breadcrumb fix

BreadCrumb change in graphql.util.DefaultTraverserContext#DefaultTraverserContext

Benchmark                                    Mode  Cnt   Score   Error  Units
SchemaBenchMark.benchMarkLargeSchemaCreate  thrpt   15  18.862 ± 1.120  ops/s

and then I applied the SchemaDirectiveWiringSchemaGeneratorPostProcessing change

After graphql.schema.idl.SchemaDirectiveWiringSchemaGeneratorPostProcessing change

Benchmark                                    Mode  Cnt   Score   Error  Units
SchemaBenchMark.benchMarkLargeSchemaCreate  thrpt   15  23.354 ± 0.996  ops/s

This is not earth shattering and we still do to many schema transforms in practice, but it's an improvement

@bbakerman bbakerman added this to the 17.0 milestone Jul 13, 2021
this.defaultDataFetcherFactory = codeRegistry.defaultDataFetcherFactory;
}

/**

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows us to mark a code registry and know if it changes since we marked it.

public Builder clearTypeResolvers() {
typeResolverMap.clear();
return this;
return markChanged();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the mutative methods mark the builder as changed

// they could have changed the code registry so rebuild it
GraphQLCodeRegistry codeRegistry = this.codeRegistryBuilder.build();
builder.codeRegistry(codeRegistry);
});

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two schema transformers here - one for a visitor that might not have done anything

And one because they MAY have changed the code registry.

Another way to fix this would be to have a way to change a schema's code registry safely (since its really a object swap in not a tree rebuild - but thats not this does

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This turned up in JProfiler as a heavily invoked bit of code in schema builds

this.breadcrumbs = ImmutableList.<Breadcrumb<T>>builderWithExpectedSize(parent.getBreadcrumbs().size() + 1)
.add(new Breadcrumb<>(this.parent.thisNode(), this.location))
.addAll(parent.getBreadcrumbs()).build();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more efficient in memory allocation and faster to boot

graphQLSchema = dummyRoot.rebuildSchema(codeRegistry);
if (postTransformation != null) {
graphQLSchema = graphQLSchema.transform(postTransformation);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BIG change - if the visitor didnt change anything and the code registry didn't change - then nothing has changed - its the same schema - so we return it direct

}
}
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can merge the netflix benchmarks in in another PR

@bbakerman bbakerman added the performance work that is primarily targeted as performance improvements label Jul 15, 2021
when:
def newSchema = SchemaTransformer.transformSchema(schema, fieldChanger)
then:
newSchema == schema

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want is or ===.
I suspect we made this error quite a lot tbh.
See https://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_relational_operators

# Conflicts:
#	src/test/groovy/graphql/schema/SchemaTransformerTest.groovy
@bbakerman bbakerman merged commit 1007fca into master Jul 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance work that is primarily targeted as performance improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants