Skip to content

Commit

Permalink
Execution Benchmarks V10 vs V11 (#2051)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Staib <michael@chillicream.com>
Co-authored-by: Michael Staib <michael.staib@chillicream.com>
  • Loading branch information
3 people committed Jun 10, 2020
1 parent 2e175bc commit 3b8fab1
Show file tree
Hide file tree
Showing 80 changed files with 2,396 additions and 154 deletions.
53 changes: 29 additions & 24 deletions src/HotChocolate/Core/.vscode/launch.json
@@ -1,25 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/benchmark/Execution.Benchmarks/bin/Debug/netcoreapp3.1/HotChocolate.Execution.Benchmarks.dll",
"args": [],
"cwd": "${workspaceFolder}/benchmark/Execution.Benchmarks",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/benchmark/Execution.Benchmarks/bin/Debug/netcoreapp3.1/HotChocolate.Execution.Benchmarks.dll",
"args": [],
"cwd": "${workspaceFolder}/benchmark/Execution.Benchmarks",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
},
{
"name": "Local Process with Kubernetes (Preview)",
"type": "dev-spaces-connect-configuration",
"request": "launch"
}
]
}
@@ -1,74 +1,144 @@
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;
using System.Buffers;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.StarWars;
using System.Threading.Tasks;
using System;
using HotChocolate.Language;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using HotChocolate.Language;
using HotChocolate.StarWars;
using Microsoft.Extensions.DependencyInjection;

namespace HotChocolate.Execution.Benchmarks
{
[RPlotExporter, CategoriesColumn, RankColumn, MeanColumn, MedianColumn, MemoryDiagnoser]
public class DefaultExecutionPipelineBenchmark
{
private readonly IRequestExecutor _executor;
private readonly IReadOnlyQueryRequest _request;
private readonly IReadOnlyQueryRequest _getHeroRequest;
private readonly IReadOnlyQueryRequest _getHeroWithFriendsRequest;
private readonly IReadOnlyQueryRequest _getTwoHerosWithFriendsRequest;
private readonly IReadOnlyQueryRequest _introspectionRequest;

public DefaultExecutionPipelineBenchmark()
{
var md5 = new MD5DocumentHashProvider();
var resources = new ResourceHelper();
var services = new ServiceCollection()
.AddStarWarsRepositories()
.AddGraphQL()
.ConfigureSchema(b => b.AddStarWarsTypes())
.Services.BuildServiceProvider();
.AddStarWarsTypes()
.Services
.BuildServiceProvider();

_executor = services
.GetRequiredService<IRequestExecutorResolver>()
.GetRequestExecutorAsync().Result;
.GetRequestExecutorAsync()
.Result;
_getHeroRequest = CreateRequest(md5, resources, "GetHeroQuery.graphql");
_getHeroWithFriendsRequest = CreateRequest(md5, resources, "GetHeroWithFriendsQuery.graphql");
_getTwoHerosWithFriendsRequest = CreateRequest(md5, resources, "GetTwoHerosWithFriendsQuery.graphql");
_introspectionRequest = CreateRequest(md5, resources, "IntrospectionQuery.graphql");
}

var md5 = new MD5DocumentHashProvider();
var resources = new ResourceHelper();
string introspectionQuery = resources.GetResourceString("IntrospectionQuery.graphql");
string hash = md5.ComputeHash(Encoding.UTF8.GetBytes(introspectionQuery).AsSpan());
DocumentNode document = Utf8GraphQLParser.Parse(introspectionQuery);
_request = QueryRequestBuilder.New()
private static IReadOnlyQueryRequest CreateRequest(
MD5DocumentHashProvider md5,
ResourceHelper resources,
string resourceName)
{
string query = resources.GetResourceString(resourceName);
string hash = md5.ComputeHash(Encoding.UTF8.GetBytes(query).AsSpan());
DocumentNode document = Utf8GraphQLParser.Parse(query);

return QueryRequestBuilder.New()
.SetQuery(document)
.SetQueryHash(hash)
.SetQueryName(hash)
.Create();
}

SchemaIntrospection().Wait();
// note : all sync
[Benchmark]
public Task SchemaIntrospection()
{
return OneRequest(_executor, _introspectionRequest);
}

[Benchmark]
public async Task SchemaIntrospection()
public Task SchemaIntrospectionFiveParallelRequests()
{
IExecutionResult result = await _executor.ExecuteAsync(_request);
return FiveRequestsInParallel(_executor, _introspectionRequest);
}

// note : 1 data fetch
[Benchmark]
public Task GetHero()
{
return OneRequest(_executor, _getHeroRequest);
}

[Benchmark]
public Task GetHeroFiveParallelRequests()
{
return FiveRequestsInParallel(_executor, _getHeroRequest);
}

// note : 2 cascading data fetches
[Benchmark]
public Task GetHeroWithFriends()
{
return OneRequest(_executor, _getHeroWithFriendsRequest);
}

[Benchmark]
public Task GetHeroWithFriendsFiveParallelRequests()
{
return FiveRequestsInParallel(_executor, _getHeroWithFriendsRequest);
}

// note : 4 data fetches (2 parallel 2 cascading)
[Benchmark]
public Task GetTwoHerosWithFriends()
{
return OneRequest(_executor, _getTwoHerosWithFriendsRequest);
}

[Benchmark]
public Task GetTwoHerosWithFriendsFiveParallelRequests()
{
return FiveRequestsInParallel(_executor, _getTwoHerosWithFriendsRequest);
}

private static async Task OneRequest(
IRequestExecutor executer,
IReadOnlyQueryRequest request)
{
IExecutionResult result = await executer.ExecuteAsync(request);
// var jsonWriter = new HotChocolate.Execution.Serialization.JsonQueryResultSerializer(true);
// Console.WriteLine(jsonWriter.Serialize((IReadOnlyQueryResult)result));
((IDisposable)result).Dispose();
}

[Benchmark]
public async Task SchemaIntrospectionMultiple()
private static async Task FiveRequestsInParallel(
IRequestExecutor executer,
IReadOnlyQueryRequest request)
{
Task<IExecutionResult> task1 = _executor.ExecuteAsync(_request);
Task<IExecutionResult> task2 = _executor.ExecuteAsync(_request);
Task<IExecutionResult> task3 = _executor.ExecuteAsync(_request);
Task<IExecutionResult> task4 = _executor.ExecuteAsync(_request);
Task<IExecutionResult> task5 = _executor.ExecuteAsync(_request);
Task task1 = OneRequest(executer, request);
Task task2 = OneRequest(executer, request);
Task task3 = OneRequest(executer, request);
Task task4 = OneRequest(executer, request);
Task task5 = OneRequest(executer, request);

((IDisposable)(await task1)).Dispose();
((IDisposable)(await task2)).Dispose();
task1 = _executor.ExecuteAsync(_request);
((IDisposable)(await task3)).Dispose();
task2 = _executor.ExecuteAsync(_request);
((IDisposable)(await task4)).Dispose();
((IDisposable)(await task5)).Dispose();
((IDisposable)(await task1)).Dispose();
((IDisposable)(await task2)).Dispose();
await WaitForTask(task1);
await WaitForTask(task2);
await WaitForTask(task3);
await WaitForTask(task4);
await WaitForTask(task5);
}

private static async Task WaitForTask(Task task)
{
if (!task.IsCompleted)
{
await task;
}
}
}
}
@@ -1,4 +1,3 @@
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using HotChocolate.Execution.Utilities;
using HotChocolate.Language;
Expand Down
Expand Up @@ -7,7 +7,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Execution\HotChocolate.Execution.csproj" />
<ProjectReference Include="..\..\test\StarWars\HotChocolate.StarWars.csproj" />
<ProjectReference Include="..\StarWars\HotChocolate.StarWars.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
@@ -0,0 +1,5 @@
query getHero {
hero(episode: NEWHOPE) {
name
}
}
@@ -0,0 +1,43 @@
query getHero {
hero(episode: NEWHOPE) {
...Hero
}
}

fragment Hero on Character {
...Human
...Droid
}

fragment Human on Human {
...HasName
...HasFriends
height
}

fragment Droid on Droid {
...HasName
...HasFriends
height
}

fragment Friend on CharacterConnection {
nodes {
...HasName
friends {
nodes {
...HasName
}
}
}
}

fragment HasName on Character {
name
}

fragment HasFriends on Character {
friends {
...Friend
}
}
@@ -0,0 +1,46 @@
query getHero {
a: hero(episode: EMPIRE) {
...Hero
}
b: hero(episode: NEWHOPE) {
...Hero
}
}

fragment Hero on Character {
...Human
...Droid
}

fragment Human on Human {
...HasName
...HasFriends
height
}

fragment Droid on Droid {
...HasName
...HasFriends
height
}

fragment Friend on CharacterConnection {
nodes {
...HasName
friends {
nodes {
...HasName
}
}
}
}

fragment HasName on Character {
name
}

fragment HasFriends on Character {
friends {
...Friend
}
}

0 comments on commit 3b8fab1

Please sign in to comment.