Skip to content

Commit 68c19c9

Browse files
committed
Improved performance of test operation
1 parent cbea188 commit 68c19c9

File tree

7 files changed

+32
-14
lines changed

7 files changed

+32
-14
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## 3.2.1
22
- Fixes an issue where null and empty string test operation of JsonNode was incorrectly handled https://github.com/Havunen/SystemTextJsonPatch/issues/31
3+
- Improved performance of JSON patch test operation
34

45
## 3.2.0
56
- Adds support for dictionary complex types https://github.com/Havunen/SystemTextJsonPatch/pull/29

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ This test deserializes a JSON patch document of 8 operations and applies the cha
6060

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

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

6969
WarmupCount=2
7070

7171
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
7272
|-------------------- |-----------:|----------:|----------:|-------:|-------:|----------:|
73-
| SystemTextJsonPatch 3.1.0 | 4.043 us | 0.0122 us | 0.0109 us | 0.2899 | - | 4.81 KB |
74-
| MarvinJsonPatch 2.2.1 | 745.778 us | 6.4053 us | 6.2909 us | 3.9063 | 1.9531 | 95.53 KB |
75-
| AspNetCoreJsonPatch 8.0.0 | 16.294 us | 0.0653 us | 0.0611 us | 2.6550 | 0.0610 | 43.61 KB |
73+
| SystemTextJsonPatch | 5.253 us | 0.0315 us | 0.0451 us | 0.3357 | - | 5.52 KB |
74+
| MarvinJsonPatch | 830.553 us | 9.1462 us | 7.6375 us | 5.8594 | 3.9063 | 104.82 KB |
75+
| AspNetCoreJsonPatch | 18.078 us | 0.1070 us | 0.0948 us | 2.9297 | 0.0610 | 48.35 KB |

SystemTextJsonPatch.Benchmark/Benchmarks/DeserializeAndApplyToBenchmark.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ public void GlobalSetup()
2323
"{{\"op\": \"replace\", \"path\": \"amount2\", \"value\": null}}," +
2424
"{{\"op\": \"replace\", \"path\": \"subTestModel\", \"value\": {{\"id\": 91117, \"data\": 78}}}}," +
2525
"{{\"op\": \"test\", \"path\": \"number\", \"value\": 86632}}," +
26-
"{{\"op\": \"copy\", \"path\": \"amount2\", \"from\": \"amount\"}}," +
26+
"{{\"op\": \"test\", \"path\": \"text\", \"value\": \"testing-performance\"}}," +
27+
"{{\"op\": \"copy\", \"path\": \"amount2\", \"from\": \"amount\"}}," +
2728
"{{\"op\": \"remove\", \"path\": \"text\"}}" + "]");
2829

2930

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
4+
namespace SystemTextJsonPatch.Internal
5+
{
6+
internal static class ByteHelper
7+
{
8+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9+
internal static bool BytesEquals(ReadOnlySpan<byte> span1, ReadOnlySpan<byte> span2)
10+
{
11+
if (span1.Length != span2.Length)
12+
{
13+
return false;
14+
}
15+
16+
return span1.SequenceEqual(span2);
17+
}
18+
}
19+
}

SystemTextJsonPatch/Internal/JSonObjectAdapter.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
8181
return false;
8282
}
8383
}
84-
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(value)?.ToString(),
85-
StringComparison.Ordinal))
84+
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(value)))
8685
{
8786
errorMessage = Resources.FormatValueNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value, segment);
8887
return false;

SystemTextJsonPatch/Internal/ListAdapter.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
163163
return false;
164164
}
165165
}
166-
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(convertedValue)?.ToString(),
167-
StringComparison.Ordinal))
166+
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(convertedValue)))
168167
{
169168
errorMessage = Resources.FormatValueAtListPositionNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value,
170169
positionInfo.Index);

SystemTextJsonPatch/Internal/PocoAdapter.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ public bool TryTest(object target, string segment, JsonSerializerOptions options
141141
return false;
142142
}
143143
}
144-
else if (!string.Equals(JsonSerializer.SerializeToNode(currentValue)?.ToString(), JsonSerializer.SerializeToNode(convertedValue)?.ToString(),
145-
StringComparison.Ordinal))
144+
else if (!ByteHelper.BytesEquals(JsonSerializer.SerializeToUtf8Bytes(currentValue), JsonSerializer.SerializeToUtf8Bytes(convertedValue)))
146145
{
147146
errorMessage = Resources.FormatValueNotEqualToTestValue(JsonSerializer.SerializeToNode(currentValue)?.ToString(), value, segment);
148147
return false;

0 commit comments

Comments
 (0)