Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 17b9069

Browse files
committed
Add perf improvements for JsConfig<T>.OnDeserializedFn / OnSerializingFn
1 parent 1a7cef6 commit 17b9069

File tree

5 files changed

+141
-4
lines changed

5 files changed

+141
-4
lines changed

src/ServiceStack.Text/Common/JsReader.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ public ParseStringDelegate GetParseFn<T>()
1515
var onDeserializedFn = JsConfig<T>.OnDeserializedFn;
1616
if (onDeserializedFn != null)
1717
{
18-
return value => onDeserializedFn((T)GetCoreParseFn<T>()(value));
18+
var parseFn = GetCoreParseFn<T>();
19+
return value => onDeserializedFn((T)parseFn(value));
1920
}
2021

2122
return GetCoreParseFn<T>();

src/ServiceStack.Text/Common/JsWriter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ public WriteObjectDelegate GetWriteFn<T>()
267267
var onSerializingFn = JsConfig<T>.OnSerializingFn;
268268
if (onSerializingFn != null)
269269
{
270-
ret = (w, x) => GetCoreWriteFn<T>()(w, onSerializingFn((T)x));
270+
var writeFn = GetCoreWriteFn<T>();
271+
ret = (w, x) => writeFn(w, onSerializingFn((T)x));
271272
}
272273

273274
if (JsConfig<T>.HasSerializeFn)
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using NUnit.Framework;
4+
using System.Diagnostics;
5+
6+
namespace ServiceStack.Text.Tests
7+
{
8+
[TestFixture]
9+
public class SerializationDelegatePerformanceTests
10+
: TestBase
11+
{
12+
[TestFixtureSetUp]
13+
public void SetUp()
14+
{
15+
AddSerializeHooksForType<PerformanceTestHookClass>();
16+
}
17+
18+
[Test]
19+
public void TypeSerializer_Deserialize_Performance_WithoutHook()
20+
{
21+
var data = GenerateData<PerformanceTestClass>();
22+
23+
var stringvalue = TypeSerializer.SerializeToString(data);
24+
25+
Stopwatch watch = Stopwatch.StartNew();
26+
var deserializedData = TypeSerializer.DeserializeFromString<List<PerformanceTestClass>>(stringvalue);
27+
watch.Stop();
28+
29+
Debug.WriteLine("Elapsed time: {0}ms", watch.ElapsedMilliseconds);
30+
31+
// should be at least less than 200ms
32+
Assert.LessOrEqual(watch.ElapsedMilliseconds, 200);
33+
}
34+
35+
[Test]
36+
public void TypeSerializer_Deserialize_Performance_WithHook()
37+
{
38+
var data = GenerateData<PerformanceTestHookClass>();
39+
40+
var stringvalue = TypeSerializer.SerializeToString(data);
41+
42+
Stopwatch watch = Stopwatch.StartNew();
43+
var deserializedData = TypeSerializer.DeserializeFromString<List<PerformanceTestHookClass>>(stringvalue);
44+
watch.Stop();
45+
46+
Debug.WriteLine("Elapsed time: {0}ms", watch.ElapsedMilliseconds);
47+
48+
// should be at least less than 600ms
49+
Assert.LessOrEqual(watch.ElapsedMilliseconds, 600);
50+
}
51+
52+
[Test]
53+
public void TypeSerializer_Serialize_Performance_WithoutHook()
54+
{
55+
var data = GenerateData<PerformanceTestClass>();
56+
57+
Stopwatch watch = Stopwatch.StartNew();
58+
var stringvalue = TypeSerializer.SerializeToString(data);
59+
watch.Stop();
60+
61+
Debug.WriteLine("Elapsed time: {0}ms", watch.ElapsedMilliseconds);
62+
63+
// should be at least less than 100ms
64+
Assert.LessOrEqual(watch.ElapsedMilliseconds, 100);
65+
}
66+
67+
[Test]
68+
public void TypeSerializer_Serialize_Performance_WithHook()
69+
{
70+
var data = GenerateData<PerformanceTestHookClass>();
71+
72+
Stopwatch watch = Stopwatch.StartNew();
73+
var stringvalue = TypeSerializer.SerializeToString(data);
74+
watch.Stop();
75+
76+
Debug.WriteLine("Elapsed time: {0}ms", watch.ElapsedMilliseconds);
77+
78+
// should be at least less than 100ms
79+
Assert.LessOrEqual(watch.ElapsedMilliseconds, 100);
80+
}
81+
82+
private List<T> GenerateData<T>() where T : PerformanceTestClass, new()
83+
{
84+
List<T> result = new List<T>();
85+
86+
for (int i = 0; i < 5000; i++)
87+
{
88+
T user = new T();
89+
user.FirstName = "Performance" + i;
90+
user.LastName = "Test";
91+
user.ID = i;
92+
user.Email = String.Format("mail{0}@test.com", i);
93+
user.UserName = "Test" + i;
94+
user.AddressID = i * 32;
95+
96+
result.Add(user);
97+
}
98+
99+
return result;
100+
}
101+
102+
public static void AddSerializeHooksForType<T>()
103+
{
104+
105+
JsConfig<T>.OnSerializingFn = s =>
106+
{
107+
return s;
108+
};
109+
110+
JsConfig<T>.OnSerializedFn = s =>
111+
{
112+
113+
};
114+
115+
JsConfig<T>.OnDeserializedFn = s =>
116+
{
117+
return s;
118+
};
119+
120+
}
121+
122+
class PerformanceTestClass : SerializationHookTests.HookTestSubClass
123+
{
124+
public string FirstName { get; set; }
125+
public string LastName { get; set; }
126+
public int ID { get; set; }
127+
public string Email { get; set; }
128+
public string UserName { get; set; }
129+
public int AddressID { get; set; }
130+
}
131+
132+
class PerformanceTestHookClass : PerformanceTestClass { }
133+
}
134+
}

tests/ServiceStack.Text.Tests/SerializationHookTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ private void AddSerializeHooksForType<T>()
141141
}
142142
}
143143

144-
class HookTestClass
144+
public class HookTestClass
145145
{
146146
public bool OnDeserializingTouched { get; set; }
147147
public bool OnDeserializedTouched { get; set; }
@@ -189,7 +189,7 @@ protected void OnSerialized(StreamingContext ctx)
189189
}
190190
}
191191

192-
class HookTestSubClass : HookTestClass
192+
public class HookTestSubClass : HookTestClass
193193
{
194194
}
195195
}

tests/ServiceStack.Text.Tests/ServiceStack.Text.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
</Reference>
177177
</ItemGroup>
178178
<ItemGroup>
179+
<Compile Include="SerializationDelegatePerformanceTests.cs" />
179180
<Compile Include="SerializationHookTests.cs" />
180181
<Compile Include="StaticAccessorTests.cs" />
181182
<Compile Include="AdhocModelTests.cs" />

0 commit comments

Comments
 (0)