diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7d62ce45..bbbba222 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ 6.0.0-preview - latest + 8.0 true true true diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/BenchmarkBase.cs b/src/GraphQLParser.Benchmarks/Benchmarks/BenchmarkBase.cs new file mode 100644 index 00000000..fbf52424 --- /dev/null +++ b/src/GraphQLParser.Benchmarks/Benchmarks/BenchmarkBase.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; + +namespace GraphQLParser.Benchmarks +{ + public abstract class BenchmarkBase : IBenchmark + { + private string _hero = null!; + private string _escapes = null!; + private string _kitchen = null!; + private string _introspection = null!; + private string _params = null!; + private string _github = null!; + + [GlobalSetup] + public virtual void GlobalSetup() + { + _hero = "hero".ReadGraphQLFile(); + _escapes = "query_with_many_escape_symbols".ReadGraphQLFile(); + _kitchen = "kitchenSink".ReadGraphQLFile(); + _introspection = "introspectionQuery".ReadGraphQLFile(); + _params = "params".ReadGraphQLFile(); + _github = "github".ReadGraphQLFile(); + } + + public string GetQueryByName(string name) + { + return name switch + { + "hero" => _hero, + "escapes" => _escapes, + "kitchen" => _kitchen, + "introspection" => _introspection, + "params" => _params, + "github" => _github, + _ => throw new System.Exception(name) + }; + } + + public IEnumerable Names() + { + yield return "hero"; + yield return "escapes"; + yield return "kitchen"; + yield return "introspection"; + yield return "params"; + yield return "github"; + } + + public abstract void Run(); + } +} diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs index 48a5d507..a3ea2a1d 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs @@ -1,29 +1,16 @@ -using System.Collections.Generic; using BenchmarkDotNet.Attributes; namespace GraphQLParser.Benchmarks { [MemoryDiagnoser] - public class LexerBenchmark : IBenchmark + public class LexerBenchmark : BenchmarkBase { - private string _escapes = null!; - private string _kitchen = null!; - private string _github = null!; - - [GlobalSetup] - public void GlobalSetup() - { - _escapes = "query_with_many_escape_symbols".ReadGraphQLFile(); - _kitchen = "kitchenSink".ReadGraphQLFile(); - _github = "github".ReadGraphQLFile(); - } - [Benchmark] - [ArgumentsSource(nameof(Queries))] - public void Lex(string query) + [ArgumentsSource(nameof(Names))] + public void Lex(string name) { var lexer = new Lexer(); - var source = new Source(query); + var source = new Source(GetQueryByName(name)); int resetPosition = 0; Token token; while ((token = lexer.Lex(source, resetPosition)).Kind != TokenKind.EOF) @@ -32,13 +19,6 @@ public void Lex(string query) } } - public IEnumerable Queries() - { - yield return _escapes; - yield return _kitchen; - yield return _github; - } - - void IBenchmark.Run() => Lex(_github); + public override void Run() => Lex("github"); } } diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs index 62fbee15..8233c57e 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs @@ -1,64 +1,21 @@ -using System.Collections.Generic; using BenchmarkDotNet.Attributes; +using GraphQLParser.AST; namespace GraphQLParser.Benchmarks { [MemoryDiagnoser] //[RPlotExporter, CsvMeasurementsExporter] - public class ParserBenchmark : IBenchmark + public class ParserBenchmark : BenchmarkBase { - private ILexemeCache? _serial; - private ILexemeCache? _concurrent; - - [GlobalSetup] - public void GlobalSetup() - { - _serial = new DictionaryCache(); - _concurrent = new ConcurrentDictionaryCache(); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Queries))] - public void Parse(Query query) - { - var parser = new Parser(new Lexer()); - parser.Parse(new Source(query.Text)); - } - - [Benchmark] - [ArgumentsSource(nameof(Queries))] - public void Serial(Query query) - { - var parser = new Parser(new Lexer() { Cache = _serial }); - parser.Parse(new Source(query.Text)); - } - [Benchmark] - [ArgumentsSource(nameof(Queries))] - public void Concurrent(Query query) - { - var parser = new Parser(new Lexer() { Cache = _concurrent }); - parser.Parse(new Source(query.Text)); - } - - public IEnumerable Queries() + [ArgumentsSource(nameof(Names))] + public GraphQLDocument Parse(string name) { - yield return new Query { Name = "Simple", Text = SMALL_QUERY }; - yield return new Query { Name = "Schema", Text = _introspectionQuery }; - yield return new Query { Name = "Params", Text = PARAMS_QUERY }; - } - - void IBenchmark.Run() => Parse(new Query { Name = "Simple", Text = SMALL_QUERY }); - - public struct Query - { - public string Text; - public string Name; - public override string ToString() => Name; + var parser = new Parser(new Lexer()); + var source = new Source(GetQueryByName(name)); + return parser.Parse(source); } - private const string SMALL_QUERY = "query test { field1 field2(id: 5) { name address } field3 }"; - private const string PARAMS_QUERY = @"query { something(name: ""one"", names: [""abc"", ""def"", ""klmn"", ""abra"", ""blabla"", ""kadabra"", ""100500""] code: 123, values: [1,2,3,4,5,6,7,8,9,0,10,20,30,40,50,60,70,80,90,100], modified: true, percents: [10.1, 20.2, 30.3, 40.4, 50.5, 60.6, 70.7], mask: [true, false, true, false, true, false], struct: { name: ""tom"", age: 42, height: 1.82, friends: [ { name: ""nik"" }, { name: ""ben"" }]}) }"; - private static readonly string _introspectionQuery = "introspectionQuery".ReadGraphQLFile(); + public override void Run() => _ = Parse("github"); } } diff --git a/src/GraphQLParser.Benchmarks/Files/hero.graphql b/src/GraphQLParser.Benchmarks/Files/hero.graphql new file mode 100644 index 00000000..d054ba1a --- /dev/null +++ b/src/GraphQLParser.Benchmarks/Files/hero.graphql @@ -0,0 +1 @@ +{ hero { id name } } diff --git a/src/GraphQLParser.Benchmarks/Files/kitchenSink.graphql b/src/GraphQLParser.Benchmarks/Files/kitchenSink.graphql index 7081f858..445eab47 100644 --- a/src/GraphQLParser.Benchmarks/Files/kitchenSink.graphql +++ b/src/GraphQLParser.Benchmarks/Files/kitchenSink.graphql @@ -41,7 +41,7 @@ subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) { } fragment frag on Friend { - foo(size: $size, bar: $b, obj: {key: ""value""}) + foo(size: $size, bar: $b, obj: {key: "value"}) } { diff --git a/src/GraphQLParser.Benchmarks/Files/params.graphql b/src/GraphQLParser.Benchmarks/Files/params.graphql new file mode 100644 index 00000000..ed7b5dca --- /dev/null +++ b/src/GraphQLParser.Benchmarks/Files/params.graphql @@ -0,0 +1 @@ +query { something(name: "one", names: ["abc", "def", "klmn", "abra", "blabla", "kadabra", "100500"] code: 123, values: [1,2,3,4,5,6,7,8,9,0,10,20,30,40,50,60,70,80,90,100], modified: true, percents: [10.1, 20.2, 30.3, 40.4, 50.5, 60.6, 70.7], mask: [true, false, true, false, true, false], struct: { name: "tom", age: 42, height: 1.82, friends: [ { name: "nik" }, { name: "ben" }]}) } diff --git a/src/GraphQLParser.Benchmarks/Program.cs b/src/GraphQLParser.Benchmarks/Program.cs index ced8f4da..f2c744b1 100644 --- a/src/GraphQLParser.Benchmarks/Program.cs +++ b/src/GraphQLParser.Benchmarks/Program.cs @@ -11,7 +11,7 @@ internal static class Program // Call without args for BenchmarkDotNet // Call with some arbitrary args for any memory profiler - private static void Main(string[] args) => Run(new[] { "args" }); + private static void Main(string[] args) => Run(args); private static void Run(string[] args) where TBenchmark : IBenchmark, new()