From 32f7d5cd825bf23348f4dfd2c0889aae9c8a389e Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sun, 10 Jan 2021 11:30:20 +0300 Subject: [PATCH 1/2] more bench --- src/Directory.Build.props | 2 +- .../Benchmarks/LexerBenchmark.cs | 34 ++++++++++++++----- .../Benchmarks/ParserBenchmark.cs | 23 +------------ .../Benchmarks/ParserBinaryBenchmark.cs | 2 +- src/GraphQLParser.Benchmarks/Program.cs | 2 +- 5 files changed, 30 insertions(+), 33 deletions(-) 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/LexerBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs index 48a5d507..8d81b42f 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs @@ -6,8 +6,10 @@ namespace GraphQLParser.Benchmarks [MemoryDiagnoser] public class LexerBenchmark : IBenchmark { + private readonly string _hero = "{ hero { id name } }"; private string _escapes = null!; private string _kitchen = null!; + private string _introspection = null!; private string _github = null!; [GlobalSetup] @@ -15,15 +17,16 @@ public void GlobalSetup() { _escapes = "query_with_many_escape_symbols".ReadGraphQLFile(); _kitchen = "kitchenSink".ReadGraphQLFile(); + _introspection = "introspectionQuery".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 = GetQueryByName(name); int resetPosition = 0; Token token; while ((token = lexer.Lex(source, resetPosition)).Kind != TokenKind.EOF) @@ -32,13 +35,28 @@ public void Lex(string query) } } - public IEnumerable Queries() + private string GetQueryByName(string name) { - yield return _escapes; - yield return _kitchen; - yield return _github; + return name switch + { + "hero" => _hero, + "escapes" => _escapes, + "kitchen" => _kitchen, + "introspection" => _introspection, + "github" => _github, + _ => throw new System.Exception(name) + }; + } + + public IEnumerable Names() + { + yield return "hero"; + yield return "escapes"; + yield return "kitchen"; + yield return "introspection"; + yield return "github"; } - void IBenchmark.Run() => Lex(_github); + void IBenchmark.Run() => Lex("github"); } } diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs index 62fbee15..171c1f8a 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs @@ -7,14 +7,9 @@ namespace GraphQLParser.Benchmarks //[RPlotExporter, CsvMeasurementsExporter] public class ParserBenchmark : IBenchmark { - private ILexemeCache? _serial; - private ILexemeCache? _concurrent; - [GlobalSetup] public void GlobalSetup() { - _serial = new DictionaryCache(); - _concurrent = new ConcurrentDictionaryCache(); } [Benchmark(Baseline = true)] @@ -22,23 +17,7 @@ public void GlobalSetup() 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)); + parser.Parse(query.Text); } public IEnumerable Queries() diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs index 11747348..a50562b0 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs @@ -20,7 +20,7 @@ public void ParseBinaryFile() try { var parser = new Parser(new Lexer()); - parser.Parse(new Source(_binaryTest)); + parser.Parse(_binaryTest); } catch (GraphQLSyntaxErrorException) { 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() From 0790465b1ddc8863aaea49d2eaba3686e023049b Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sun, 10 Jan 2021 12:51:46 +0300 Subject: [PATCH 2/2] unify bench --- .../Benchmarks/BenchmarkBase.cs | 52 +++++++++++++++++++ .../Benchmarks/LexerBenchmark.cs | 44 ++-------------- .../Benchmarks/ParserBenchmark.cs | 38 +++----------- .../Benchmarks/ParserBinaryBenchmark.cs | 2 +- .../Files/hero.graphql | 1 + .../Files/kitchenSink.graphql | 2 +- .../Files/params.graphql | 1 + 7 files changed, 67 insertions(+), 73 deletions(-) create mode 100644 src/GraphQLParser.Benchmarks/Benchmarks/BenchmarkBase.cs create mode 100644 src/GraphQLParser.Benchmarks/Files/hero.graphql create mode 100644 src/GraphQLParser.Benchmarks/Files/params.graphql 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 8d81b42f..a3ea2a1d 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/LexerBenchmark.cs @@ -1,32 +1,16 @@ -using System.Collections.Generic; using BenchmarkDotNet.Attributes; namespace GraphQLParser.Benchmarks { [MemoryDiagnoser] - public class LexerBenchmark : IBenchmark + public class LexerBenchmark : BenchmarkBase { - private readonly string _hero = "{ hero { id name } }"; - private string _escapes = null!; - private string _kitchen = null!; - private string _introspection = null!; - private string _github = null!; - - [GlobalSetup] - public void GlobalSetup() - { - _escapes = "query_with_many_escape_symbols".ReadGraphQLFile(); - _kitchen = "kitchenSink".ReadGraphQLFile(); - _introspection = "introspectionQuery".ReadGraphQLFile(); - _github = "github".ReadGraphQLFile(); - } - [Benchmark] [ArgumentsSource(nameof(Names))] public void Lex(string name) { var lexer = new Lexer(); - var source = GetQueryByName(name); + var source = new Source(GetQueryByName(name)); int resetPosition = 0; Token token; while ((token = lexer.Lex(source, resetPosition)).Kind != TokenKind.EOF) @@ -35,28 +19,6 @@ public void Lex(string name) } } - private string GetQueryByName(string name) - { - return name switch - { - "hero" => _hero, - "escapes" => _escapes, - "kitchen" => _kitchen, - "introspection" => _introspection, - "github" => _github, - _ => throw new System.Exception(name) - }; - } - - public IEnumerable Names() - { - yield return "hero"; - yield return "escapes"; - yield return "kitchen"; - yield return "introspection"; - 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 171c1f8a..8233c57e 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs @@ -1,43 +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 { - [GlobalSetup] - public void GlobalSetup() - { - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Queries))] - public void Parse(Query query) + [Benchmark] + [ArgumentsSource(nameof(Names))] + public GraphQLDocument Parse(string name) { var parser = new Parser(new Lexer()); - parser.Parse(query.Text); - } - - public IEnumerable Queries() - { - 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 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/Benchmarks/ParserBinaryBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs index a50562b0..11747348 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBinaryBenchmark.cs @@ -20,7 +20,7 @@ public void ParseBinaryFile() try { var parser = new Parser(new Lexer()); - parser.Parse(_binaryTest); + parser.Parse(new Source(_binaryTest)); } catch (GraphQLSyntaxErrorException) { 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" }]}) }