Skip to content
This repository has been archived by the owner on Feb 15, 2021. It is now read-only.

Commit

Permalink
reworked benchmark test
Browse files Browse the repository at this point in the history
  • Loading branch information
gregsdennis committed Dec 12, 2019
1 parent a0b7c69 commit 1d7f34f
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 95 deletions.
30 changes: 30 additions & 0 deletions Manatee.Json.Tests.Benchmark/Emoji.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using Manatee.Json.Serialization;

namespace Manatee.Json.Tests.Benchmark
{
public class EmojiResponse
{
public List<LocalEmoji> Trello { get; set; }
}

public class LocalEmoji
{
// functions as ID
public string Unified { get; set; }
public string Native { get; set; }
public string Name { get; set; }
public string ShortName { get; set; }
public List<string> ShortNames { get; set; }
public string Text { get; set; }
public List<string> Texts { get; set; }
public string Category { get; set; }
public int SheetX { get; set; }
public int SheetY { get; set; }
public string Tts { get; set; }
public List<string> Keywords { get; set; }
public Dictionary<string, LocalEmoji> SkinVariations { get; set; }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
152 changes: 98 additions & 54 deletions Manatee.Json.Tests.Benchmark/PerformanceTests.cs
Original file line number Diff line number Diff line change
@@ -1,100 +1,144 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using JsonSerializer = Manatee.Json.Serialization.JsonSerializer;

namespace Manatee.Json.Tests.Benchmark
{
public class PerformanceTests
public static class PerformanceTests
{
public class MyClass
private static readonly JsonSerializer _serializer = new JsonSerializer
{
Options =
{
CaseSensitiveDeserialization = false
}
};
private static readonly Stopwatch _manateeWatch = new Stopwatch();
private static long _parseTime;
private static long _serializeTime;
private static long _deserializeTime;
private static long _toStringTime;
private static bool _shouldOutput;

public static async Task Run()
{
public string Value { get; set; }
public int OtherValue { get; set; }
public MyClass NestedValue { get; set; }
await _RunBulk();
}

private static readonly JsonSerializer _serializer = new JsonSerializer();

public static void Run()
private static async Task _RunBulk()
{
// This initializes whatever caches might be inside the serializer
//_RunSingle(false);

//_RunSingle();
_RunBulk();
var data = await GetEmojiData();
Console.WriteLine($"Data length: {data.Length}");
Console.WriteLine($"Object count: 1528");

var runCount = 100;
var page = 10;
for (int i = 0; i < runCount; i++)
{
_shouldOutput = i % page == 0 || i == runCount - 1;
Log($"Run {i}");
_ExecuteTest(data);
Log();
Log();
}
}

private static void _RunSingle(bool output = true)
private static void _ExecuteTest(string data)
{
var subjects = new[] {_GenerateSubject()};

if (output)
Console.WriteLine("\nNewtonsoft @1");
//_Run(subjects, JsonConvert.SerializeObject, JsonConvert.DeserializeObject<MyClass>, output);

if (output)
Console.WriteLine("\nManatee @1");
_Run(subjects, _ManateeSerialize, _ManateeDeserialize, output);
}
_parseTime = 0;
_deserializeTime = 0;
_serializeTime = 0;
_toStringTime = 0;

private static void _RunBulk()
{
var count = 100000;
var subjects = Enumerable.Range(0, count).Select(i => _GenerateSubject()).ToList();
Log($"\nNewtonsoft");
_Run(data, JsonConvert.SerializeObject, JsonConvert.DeserializeObject<EmojiResponse>);

Console.WriteLine($"\nNewtonsoft @{count}");
_Run(subjects, JsonConvert.SerializeObject, JsonConvert.DeserializeObject<MyClass>);
Log($"\nManatee");
_Run(data, _ManateeSerialize, _ManateeDeserialize, true);

Console.WriteLine($"\nManatee @{count}");
_Run(subjects, _ManateeSerialize, _ManateeDeserialize);
}

private static void _Run(IEnumerable<MyClass> subjects, Func<MyClass, string> serialize, Func<string, MyClass> deserialize, bool output = true)
private static void _Run(string data, Func<EmojiResponse, string> serialize, Func<string, EmojiResponse> deserialize, bool details = false)
{
Thread.Sleep(1);

var watch = new Stopwatch();

watch.Start();
var json = subjects.Select(serialize).ToArray();
var objects = deserialize(data);
watch.Stop();

if (output)
Console.WriteLine($" Serialize: {watch.Elapsed}");

Log($" Deserialize: {watch.Elapsed}");
if (details)
{
Log($" Parse: {TimeSpan.FromTicks(_parseTime)}");
Log($" Deserialize: {TimeSpan.FromTicks(_deserializeTime)}");
}

watch.Reset();
watch.Start();
var back = json.Select(deserialize).ToArray();
var json = serialize(objects);
watch.Stop();

if (output)
Console.WriteLine($" Deserialize: {watch.Elapsed}");
Log($" Serialize: {watch.Elapsed}");
if (details)
{
Log($" Serialize: {TimeSpan.FromTicks(_serializeTime)}");
Log($" ToString: {TimeSpan.FromTicks(_toStringTime)}");
}
}

private static string _ManateeSerialize(MyClass obj)
private static string _ManateeSerialize(EmojiResponse obj)
{
_manateeWatch.Reset();
_manateeWatch.Start();
var json = _serializer.Serialize(obj);
return json.ToString();
_manateeWatch.Stop();
_serializeTime += _manateeWatch.ElapsedTicks;

_manateeWatch.Reset();
_manateeWatch.Start();
var str = json.ToString();
_manateeWatch.Stop();
_toStringTime += _manateeWatch.ElapsedTicks;

return str;
}

private static MyClass _ManateeDeserialize(string jsonString)
private static EmojiResponse _ManateeDeserialize(string jsonString)
{
_manateeWatch.Reset();
_manateeWatch.Start();
var json = JsonValue.Parse(jsonString);
return _serializer.Deserialize<MyClass>(json);
_manateeWatch.Stop();
_parseTime += _manateeWatch.ElapsedTicks;

_manateeWatch.Reset();
_manateeWatch.Start();
var obj = _serializer.Deserialize<EmojiResponse>(json);
_manateeWatch.Stop();
_deserializeTime += _manateeWatch.ElapsedTicks;

return obj;
}

private static async Task<string> GetEmojiData()
{
using (var client = new HttpClient())
using (var response = await client.GetAsync("https://api.trello.com/1/emoji?spritesheets=false&key=062109670e7f56b88783721892f8f66f"))
{
return await response.Content.ReadAsStringAsync();
}
}

private static MyClass _GenerateSubject(int nest = 0)
private static void Log(string message = null)
{
return new MyClass
{
Value = Guid.NewGuid().ToString(),
OtherValue = new Random().Next(),
NestedValue = nest < 3 && new Random().Next(10)%2 == 0 ? _GenerateSubject(nest + 1) : null
};
if (_shouldOutput)
Console.WriteLine(message);
}
}
}
5 changes: 3 additions & 2 deletions Manatee.Json.Tests.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Threading.Tasks;

namespace Manatee.Json.Tests.Benchmark
{
class Program
{
static void Main(string[] args)
static async Task Main(string[] args)
{
PerformanceTests.Run();
await PerformanceTests.Run();

Console.ReadLine();
}
Expand Down
33 changes: 33 additions & 0 deletions Manatee.Json.Tests.Benchmark/SkinVariationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Manatee.Json.Tests.Benchmark
{
/// <summary>
/// Enumerates the various skin tone variations for <see cref="Emoji"/>s.
/// </summary>
public enum SkinVariationType
{
/// <summary>
/// No variation (yellow).
/// </summary>
None,
/// <summary>
/// Light skin.
/// </summary>
Light,
/// <summary>
/// Medium light skin.
/// </summary>
MediumLight,
/// <summary>
/// Medium skin.
/// </summary>
Medium,
/// <summary>
/// Medium dark skin.
/// </summary>
MediumDark,
/// <summary>
/// Dark skin.
/// </summary>
Dark
}
}
8 changes: 4 additions & 4 deletions Manatee.Json.Tests/Manatee.Json.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

<ItemGroup>
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Humanizer" Version="2.6.2" />
<PackageReference Include="Humanizer" Version="2.7.9" />
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.0.20171219.105559" />
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 0 additions & 4 deletions Manatee.Json/JsonArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ public string GetIndentedString(int indentLevel = 0)
if (Count == 0) return "[]";

var builder = new StringBuilder();

AppendIndentedString(builder, indentLevel);

return builder.ToString();
}
internal void AppendIndentedString(StringBuilder builder, int indentLevel)
Expand Down Expand Up @@ -104,9 +102,7 @@ public override string ToString()
if (Count == 0) return "[]";

var builder = new StringBuilder();

AppendString(builder);

return builder.ToString();
}

Expand Down
4 changes: 0 additions & 4 deletions Manatee.Json/JsonObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ public string GetIndentedString(int indentLevel = 0)
if (Count == 0) return "{}";

var builder = new StringBuilder();

AppendIndentedString(builder, indentLevel);

return builder.ToString();
}
internal void AppendIndentedString(StringBuilder builder, int indentLevel = 0)
Expand Down Expand Up @@ -114,9 +112,7 @@ public override string ToString()
if (Count == 0) return "{}";

var builder = new StringBuilder();

AppendString(builder);

return builder.ToString();
}
internal void AppendString(StringBuilder builder)
Expand Down
30 changes: 6 additions & 24 deletions Manatee.Json/JsonValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,9 @@ public JsonValue(JsonValue other)
/// <returns>A string.</returns>
public string GetIndentedString(int indentLevel = 0)
{
switch (Type)
{
case JsonValueType.Object:
return _objectValue.GetIndentedString(indentLevel);
case JsonValueType.Array:
return _arrayValue.GetIndentedString(indentLevel);
default:
return ToString();
}
var builder = new StringBuilder();
AppendIndentedString(builder, indentLevel);
return builder.ToString();
}
internal void AppendIndentedString(StringBuilder builder, int indentLevel)
{
Expand All @@ -258,21 +252,9 @@ internal void AppendIndentedString(StringBuilder builder, int indentLevel)
/// </remarks>
public override string ToString()
{
switch (Type)
{
case JsonValueType.Number:
return string.Format(CultureInfo.InvariantCulture, "{0}", _numberValue);
case JsonValueType.String:
return string.Concat("\"", _stringValue.InsertEscapeSequences(), "\"");
case JsonValueType.Boolean:
return _boolValue ? "true" : "false";
case JsonValueType.Object:
return _objectValue.ToString();
case JsonValueType.Array:
return _arrayValue.ToString();
default:
return "null";
}
var stringBuilder = new StringBuilder();
AppendString(stringBuilder);
return stringBuilder.ToString();
}
internal void AppendString(StringBuilder builder)
{
Expand Down
Loading

0 comments on commit 1d7f34f

Please sign in to comment.