-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added some benchmarks, optimized SnakeCaseNamingPolicy
- Loading branch information
Showing
7 changed files
with
2,402 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System; | ||
using System.IO; | ||
using System.Text.Json; | ||
using BenchmarkDotNet.Attributes; | ||
using Gw2Sharp.WebApi.V2; | ||
using Gw2Sharp.WebApi.V2.Models; | ||
|
||
namespace Gw2Sharp.Benchmarks | ||
{ | ||
[MedianColumn] | ||
[MemoryDiagnoser] | ||
public class ItemsPageDeserializeBenchmark | ||
{ | ||
private const int OPERATIONS_PER_INVOKE = 50; | ||
private byte[] jsonBytes = Array.Empty<byte>(); | ||
private JsonSerializerOptions? jsonSerializerOptions = null; | ||
private object? dump; | ||
|
||
[GlobalSetup] | ||
public void GlobalSetup() | ||
{ | ||
string path = Path.Combine("TestFiles", "Items", "Items.max_page_size.json"); | ||
this.jsonBytes = System.IO.File.ReadAllBytes(path); | ||
this.jsonSerializerOptions = SerializationHelpers.GetJsonSerializerOptions(); | ||
} | ||
|
||
[Benchmark(OperationsPerInvoke=OPERATIONS_PER_INVOKE)] | ||
public object DeserializeItemsPage() | ||
{ | ||
for (int i = 0; i < OPERATIONS_PER_INVOKE; ++i) | ||
{ | ||
this.dump = JsonSerializer.Deserialize<IApiV2ObjectList<Item>>(this.jsonBytes, this.jsonSerializerOptions); | ||
} | ||
|
||
return this.dump!; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System.Threading.Tasks; | ||
using BenchmarkDotNet.Attributes; | ||
|
||
namespace Gw2Sharp.Benchmarks | ||
{ | ||
/// <summary> | ||
/// This benchmark essentially checks how much time | ||
/// it takes to retrieve items page from the cache. | ||
/// The page is initially loaded in <see cref="GlobalSetupAsync"/> | ||
/// via <see cref="Gw2Client"/> once and retrieved from the same | ||
/// instance during the benchmark. | ||
/// </summary> | ||
[MedianColumn] | ||
[MemoryDiagnoser] | ||
public class ItemsPageGetCachedBenchmark | ||
{ | ||
private const int OPERATIONS_PER_INVOKE = 10; | ||
private Connection? connection; | ||
private Gw2Client? gw2Client; | ||
private object? dump; | ||
|
||
[GlobalSetup] | ||
public async Task GlobalSetupAsync() | ||
{ | ||
this.connection = new Connection(); | ||
this.gw2Client = new Gw2Client(this.connection); | ||
await this.gw2Client.WebApi.V2.Items.PageAsync(1).ConfigureAwait(false); | ||
} | ||
|
||
[GlobalCleanup] | ||
public void GlobalCleanup() => this.gw2Client!.Dispose(); | ||
|
||
[Benchmark(OperationsPerInvoke=OPERATIONS_PER_INVOKE)] | ||
public async Task<object?> DeserializeItemsBulkFastestAsync() | ||
{ | ||
for (int i = 0; i < OPERATIONS_PER_INVOKE; ++i) | ||
{ | ||
this.dump = await this.gw2Client!.WebApi.V2.Items.PageAsync(1).ConfigureAwait(false); | ||
} | ||
|
||
return this.dump; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
using System.Text.Json; | ||
using Gw2Sharp.Json; | ||
using Gw2Sharp.Json.Converters; | ||
|
||
namespace Gw2Sharp.Benchmarks | ||
{ | ||
public class SerializationHelpers | ||
{ | ||
public static JsonSerializerOptions GetJsonSerializerOptions() | ||
{ | ||
var options = new JsonSerializerOptions | ||
{ | ||
AllowTrailingCommas = true, | ||
PropertyNameCaseInsensitive = true, | ||
PropertyNamingPolicy = SnakeCaseNamingPolicy.SnakeCase | ||
}; | ||
options.Converters.Add(new ApiEnumConverter()); | ||
options.Converters.Add(new ApiFlagsConverter()); | ||
options.Converters.Add(new ApiObjectConverter()); | ||
options.Converters.Add(new ApiObjectListConverter()); | ||
options.Converters.Add(new CastableTypeConverter()); | ||
options.Converters.Add(new DictionaryIntKeyConverter()); | ||
options.Converters.Add(new RenderUrlConverter(new Connection(), null!)); | ||
options.Converters.Add(new TimeSpanConverter()); | ||
return options; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Gw2Sharp.Json; | ||
|
||
namespace Gw2Sharp.Benchmarks | ||
{ | ||
[MedianColumn] | ||
[MemoryDiagnoser] | ||
public class SnakeCaseJsonNamingPolicyBenchmark | ||
{ | ||
private const int OPERATIONS_PER_INVOKE = 1_000_000; | ||
private static readonly SnakeCaseNamingPolicy policy = SnakeCaseNamingPolicy.SnakeCase; | ||
private const string CONVENTIONAL_PROPERTY_NAME = "HypotheticalPropertyNameWithUnrealisticlyManyWords"; | ||
private const string UNCONVENTIONAL_PROPERTY_NAME = "HyPOThETicAl_PRopeRtYnAmE_wiThUNReAlisTicLyMaNy_wOrDs"; | ||
private object? dump; | ||
|
||
[Benchmark(OperationsPerInvoke=OPERATIONS_PER_INVOKE)] | ||
public object? ConvertConventionalPropertyNameFast() | ||
{ | ||
for (int i = 0; i < OPERATIONS_PER_INVOKE; ++i) | ||
{ | ||
this.dump = policy.ConvertName(CONVENTIONAL_PROPERTY_NAME); | ||
} | ||
|
||
return this.dump; | ||
} | ||
|
||
[Benchmark(OperationsPerInvoke=OPERATIONS_PER_INVOKE)] | ||
public object? ConvertUnconventionalPropertyNameFast() | ||
{ | ||
for (int i = 0; i < OPERATIONS_PER_INVOKE; ++i) | ||
{ | ||
this.dump = policy.ConvertName(UNCONVENTIONAL_PROPERTY_NAME); | ||
} | ||
|
||
return this.dump; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using Gw2Sharp.Json; | ||
using Xunit; | ||
|
||
namespace Gw2Sharp.Tests.Json.Converters | ||
{ | ||
public class SnakeCaseNamingPolicyTests | ||
{ | ||
[Fact] | ||
public void ConvertsUpperCamelCase() | ||
{ | ||
const string propertyName = "UpperCamelCasePropertyName"; | ||
string convertedPropertyName = SnakeCaseNamingPolicy.SnakeCase.ConvertName(propertyName); | ||
Assert.Equal("upper_camel_case_property_name", convertedPropertyName); | ||
} | ||
|
||
[Fact] | ||
public void ConvertsLowerCamelCase() | ||
{ | ||
const string propertyName = "lowerCamelCasePropertyName"; | ||
string convertedPropertyName = SnakeCaseNamingPolicy.SnakeCase.ConvertName(propertyName); | ||
Assert.Equal("lower_camel_case_property_name", convertedPropertyName); | ||
} | ||
|
||
[Fact] | ||
public void PreservesSnakeCase() | ||
{ | ||
const string propertyName = "snake_case_property_name"; | ||
string convertedPropertyName = SnakeCaseNamingPolicy.SnakeCase.ConvertName(propertyName); | ||
Assert.Equal(propertyName, convertedPropertyName); | ||
} | ||
|
||
[Theory] | ||
[InlineData("GuildWars2EOD", "guild_wars2_eod")] | ||
[InlineData("GW2EndOfDragons", "gw2_end_of_dragons")] | ||
[InlineData("LWSeason2", "lwseason2")] | ||
[InlineData("LW_Season2", "lw_season2")] | ||
public void HandlesAcronyms(string propertyName, string expectedConvertedPropertyName) | ||
{ | ||
string convertedPropertyName = SnakeCaseNamingPolicy.SnakeCase.ConvertName(propertyName); | ||
Assert.Equal(expectedConvertedPropertyName, convertedPropertyName); | ||
} | ||
} | ||
} |
Oops, something went wrong.