Skip to content

Commit

Permalink
Improved performance of test operation
Browse files Browse the repository at this point in the history
  • Loading branch information
Havunen committed Aug 7, 2024
1 parent cbea188 commit 68c19c9
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 3.2.1
- Fixes an issue where null and empty string test operation of JsonNode was incorrectly handled https://github.com/Havunen/SystemTextJsonPatch/issues/31
- Improved performance of JSON patch test operation

## 3.2.0
- Adds support for dictionary complex types https://github.com/Havunen/SystemTextJsonPatch/pull/29
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ This test deserializes a JSON patch document of 8 operations and applies the cha

See [SystemTextJsonPatch.Benchmark](https://github.com/Havunen/SystemTextJsonPatch/tree/main/SystemTextJsonPatch.Benchmark) for more details.

BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2428/22H2/2022Update/SunValley2)
BenchmarkDotNet v0.14.0, Windows 11 (10.0.22631.3880/23H2/2023Update/SunValley3)
AMD Ryzen 9 5950X, 1 CPU, 32 logical and 16 physical cores
.NET SDK 8.0.100
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
Job-NISUXQ : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
.NET SDK 8.0.400-preview.0.24324.5
[Host] : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2
Job-FECQKB : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2

WarmupCount=2

| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|-------------------- |-----------:|----------:|----------:|-------:|-------:|----------:|
| SystemTextJsonPatch 3.1.0 | 4.043 us | 0.0122 us | 0.0109 us | 0.2899 | - | 4.81 KB |
| MarvinJsonPatch 2.2.1 | 745.778 us | 6.4053 us | 6.2909 us | 3.9063 | 1.9531 | 95.53 KB |
| AspNetCoreJsonPatch 8.0.0 | 16.294 us | 0.0653 us | 0.0611 us | 2.6550 | 0.0610 | 43.61 KB |
| SystemTextJsonPatch | 5.253 us | 0.0315 us | 0.0451 us | 0.3357 | - | 5.52 KB |
| MarvinJsonPatch | 830.553 us | 9.1462 us | 7.6375 us | 5.8594 | 3.9063 | 104.82 KB |
| AspNetCoreJsonPatch | 18.078 us | 0.1070 us | 0.0948 us | 2.9297 | 0.0610 | 48.35 KB |
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public void GlobalSetup()
"{{\"op\": \"replace\", \"path\": \"amount2\", \"value\": null}}," +
"{{\"op\": \"replace\", \"path\": \"subTestModel\", \"value\": {{\"id\": 91117, \"data\": 78}}}}," +
"{{\"op\": \"test\", \"path\": \"number\", \"value\": 86632}}," +
"{{\"op\": \"copy\", \"path\": \"amount2\", \"from\": \"amount\"}}," +
"{{\"op\": \"test\", \"path\": \"text\", \"value\": \"testing-performance\"}}," +
"{{\"op\": \"copy\", \"path\": \"amount2\", \"from\": \"amount\"}}," +
"{{\"op\": \"remove\", \"path\": \"text\"}}" + "]");


Expand Down
19 changes: 19 additions & 0 deletions SystemTextJsonPatch/Internal/ByteHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Runtime.CompilerServices;

namespace SystemTextJsonPatch.Internal
{
internal static class ByteHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool BytesEquals(ReadOnlySpan<byte> span1, ReadOnlySpan<byte> span2)
{
if (span1.Length != span2.Length)
{
return false;
}

return span1.SequenceEqual(span2);
}
}
}
3 changes: 1 addition & 2 deletions SystemTextJsonPatch/Internal/JSonObjectAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
return false;
}
}
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(value)?.ToString(),
StringComparison.Ordinal))
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(value)))
{
errorMessage = Resources.FormatValueNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value, segment);
return false;
Expand Down
3 changes: 1 addition & 2 deletions SystemTextJsonPatch/Internal/ListAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
return false;
}
}
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(convertedValue)?.ToString(),
StringComparison.Ordinal))
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(convertedValue)))
{
errorMessage = Resources.FormatValueAtListPositionNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value,
positionInfo.Index);
Expand Down
3 changes: 1 addition & 2 deletions SystemTextJsonPatch/Internal/PocoAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
return false;
}
}
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(convertedValue)?.ToString(),
StringComparison.Ordinal))
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(convertedValue)))
{
errorMessage = Resources.FormatValueNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value, segment);
return false;
Expand Down

0 comments on commit 68c19c9

Please sign in to comment.