diff --git a/Benchmarks/Schema.NET.Benchmarks/Core/BookBenchmark.cs b/Benchmarks/Schema.NET.Benchmarks/Core/BookBenchmark.cs new file mode 100644 index 00000000..f35b4a2b --- /dev/null +++ b/Benchmarks/Schema.NET.Benchmarks/Core/BookBenchmark.cs @@ -0,0 +1,82 @@ +namespace Schema.NET.Benchmarks.Core +{ + using System; + using System.Collections.Generic; + using BenchmarkDotNet.Attributes; + + public class BookBenchmark : SchemaBenchmarkBase + { + [GlobalSetup] + public void Setup() => this.ConfigureBenchmark(new Book() + { + Id = new Uri("http://example.com/book/1"), + Name = "The Catcher in the Rye", + Author = new Person() + { + Name = "J.D. Salinger" + }, + Url = new Uri("http://www.barnesandnoble.com/store/info/offer/JDSalinger"), + WorkExample = new List() + { + new Book() + { + Isbn = "031676948", + BookEdition = "2nd Edition", + BookFormat = BookFormatType.Hardcover, + PotentialAction = new ReadAction() + { + Target = new EntryPoint() + { + UrlTemplate = "http://www.barnesandnoble.com/store/info/offer/0316769487?purchase=true", + ActionPlatform = new List() + { + new Uri("https://schema.org/DesktopWebPlatform"), + new Uri("https://schema.org/IOSPlatform"), + new Uri("https://schema.org/AndroidPlatform") + } + }, + ExpectsAcceptanceOf = new Offer() + { + Price = 6.99M, + PriceCurrency = "USD", + EligibleRegion = new Country() + { + Name = "US" + }, + Availability = ItemAvailability.InStock + } + }, + }, + new Book() + { + Isbn = "031676947", + BookEdition = "1st Edition", + BookFormat = BookFormatType.EBook, + PotentialAction = new ReadAction() + { + Target = new EntryPoint() + { + UrlTemplate = "http://www.barnesandnoble.com/store/info/offer/031676947?purchase=true", + ActionPlatform = new List() + { + new Uri("https://schema.org/DesktopWebPlatform"), + new Uri("https://schema.org/IOSPlatform"), + new Uri("https://schema.org/AndroidPlatform") + } + }, + ExpectsAcceptanceOf = new Offer() + { + Price = 1.99M, + PriceCurrency = "USD", + EligibleRegion = new Country() + { + Name = "UK" + }, + Availability = ItemAvailability.InStock + } + }, + } + } + }); + } +} diff --git a/Benchmarks/Schema.NET.Benchmarks/Core/WebsiteBenchmark.cs b/Benchmarks/Schema.NET.Benchmarks/Core/WebsiteBenchmark.cs new file mode 100644 index 00000000..e8dd12ca --- /dev/null +++ b/Benchmarks/Schema.NET.Benchmarks/Core/WebsiteBenchmark.cs @@ -0,0 +1,19 @@ +namespace Schema.NET.Benchmarks.Core +{ + using System; + using BenchmarkDotNet.Attributes; + + public class WebsiteBenchmark : SchemaBenchmarkBase + { + [GlobalSetup] + public void Setup() => this.ConfigureBenchmark(new WebSite() + { + PotentialAction = new SearchAction() + { + Target = new Uri("http://example.com/search?&q={query}"), + QueryInput = "required" + }, + Url = new Uri("https://example.com") + }); + } +} diff --git a/Benchmarks/Schema.NET.Benchmarks/Program.cs b/Benchmarks/Schema.NET.Benchmarks/Program.cs new file mode 100644 index 00000000..6e37d6ff --- /dev/null +++ b/Benchmarks/Schema.NET.Benchmarks/Program.cs @@ -0,0 +1,10 @@ +namespace Schema.NET.Benchmarks +{ + using System; + using BenchmarkDotNet.Running; + + internal class Program + { + private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); + } +} diff --git a/Benchmarks/Schema.NET.Benchmarks/Schema.NET.Benchmarks.csproj b/Benchmarks/Schema.NET.Benchmarks/Schema.NET.Benchmarks.csproj new file mode 100644 index 00000000..3828c8d0 --- /dev/null +++ b/Benchmarks/Schema.NET.Benchmarks/Schema.NET.Benchmarks.csproj @@ -0,0 +1,27 @@ + + + + Exe + net472;netcoreapp3.0 + ../../MinimumRecommendedRulesWithStyleCop.ruleset + latest + true + + + + + + + + + + + + + + + + + + + diff --git a/Benchmarks/Schema.NET.Benchmarks/SchemaBenchmarkBase.cs b/Benchmarks/Schema.NET.Benchmarks/SchemaBenchmarkBase.cs new file mode 100644 index 00000000..34c39f3e --- /dev/null +++ b/Benchmarks/Schema.NET.Benchmarks/SchemaBenchmarkBase.cs @@ -0,0 +1,38 @@ +namespace Schema.NET.Benchmarks +{ + using System; + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Jobs; + using Newtonsoft.Json; + + [KeepBenchmarkFiles] + [MemoryDiagnoser] + [MinColumn] + [MaxColumn] + [HtmlExporter] + [CsvMeasurementsExporter] + [RPlotExporter] + [SimpleJob(RuntimeMoniker.Net472)] + [SimpleJob(RuntimeMoniker.NetCoreApp30)] + public abstract class SchemaBenchmarkBase + { + protected Thing Thing { get; set; } + + private Type ThingType { get; set; } + + private string SerializedThing { get; set; } + + [Benchmark] + public string Serialize() => this.Thing.ToString(); + + [Benchmark] + public object Deserialize() => JsonConvert.DeserializeObject(this.SerializedThing, this.ThingType); + + protected void ConfigureBenchmark(Thing thing) + { + this.Thing = thing; + this.ThingType = this.Thing.GetType(); + this.SerializedThing = this.Thing.ToString(); + } + } +} diff --git a/Schema.NET.sln b/Schema.NET.sln index 178d4ef0..a1126530 100644 --- a/Schema.NET.sln +++ b/Schema.NET.sln @@ -55,6 +55,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{0555 .github\SECURITY.md = .github\SECURITY.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{E25F6292-80CE-45FE-97B0-0EBBF8E1FC6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Schema.NET.Benchmarks", "Benchmarks\Schema.NET.Benchmarks\Schema.NET.Benchmarks.csproj", "{EA1CBFC3-F165-4811-AA9F-157DEB8E31CC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +77,10 @@ Global {3E75002C-0EF2-4F04-8EC6-CED90BA27AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E75002C-0EF2-4F04-8EC6-CED90BA27AD1}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E75002C-0EF2-4F04-8EC6-CED90BA27AD1}.Release|Any CPU.Build.0 = Release|Any CPU + {EA1CBFC3-F165-4811-AA9F-157DEB8E31CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA1CBFC3-F165-4811-AA9F-157DEB8E31CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA1CBFC3-F165-4811-AA9F-157DEB8E31CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA1CBFC3-F165-4811-AA9F-157DEB8E31CC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,6 +91,7 @@ Global {3E75002C-0EF2-4F04-8EC6-CED90BA27AD1} = {E1B24F25-B8A4-46EE-B7EB-7803DCFC543F} {566DF0E2-1288-4083-9B55-4C8B69BB1432} = {0555C737-CE4B-4C78-87AB-6296E1E32D01} {0555C737-CE4B-4C78-87AB-6296E1E32D01} = {7EDFA103-DB69-4C88-9DE4-97ADBF8253A1} + {EA1CBFC3-F165-4811-AA9F-157DEB8E31CC} = {E25F6292-80CE-45FE-97B0-0EBBF8E1FC6A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {73F36209-F8D6-4066-8951-D97729F773CF}