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

Commit 597433d

Browse files
committed
Merge branch 'master' of github.com:ServiceStack/ServiceStack.Text
2 parents 4e06be2 + d8b9100 commit 597433d

13 files changed

+357
-3
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
using System;
2+
using System.IO;
3+
using System.Text;
4+
using BenchmarkDotNet.Attributes;
5+
using ServiceStack.Text;
6+
using ServiceStack.Text.Tests.DynamicModels;
7+
using ServiceStack.Text.Json;
8+
9+
namespace ServiceStack.Text.Benchmarks
10+
{
11+
public class ModelWithCommonTypes
12+
{
13+
public char CharValue { get; set; }
14+
15+
public byte ByteValue { get; set; }
16+
17+
public sbyte SByteValue { get; set; }
18+
19+
public short ShortValue { get; set; }
20+
21+
public ushort UShortValue { get; set; }
22+
23+
public int IntValue { get; set; }
24+
25+
public uint UIntValue { get; set; }
26+
27+
public long LongValue { get; set; }
28+
29+
public ulong ULongValue { get; set; }
30+
31+
public float FloatValue { get; set; }
32+
33+
public double DoubleValue { get; set; }
34+
35+
public decimal DecimalValue { get; set; }
36+
37+
public DateTime DateTimeValue { get; set; }
38+
39+
public TimeSpan TimeSpanValue { get; set; }
40+
41+
public Guid GuidValue { get; set; }
42+
43+
public static ModelWithCommonTypes Create(byte i)
44+
{
45+
return new ModelWithCommonTypes
46+
{
47+
ByteValue = i,
48+
CharValue = (char)i,
49+
DateTimeValue = new DateTime(2000, 1, 1 + i),
50+
DecimalValue = i,
51+
DoubleValue = i,
52+
FloatValue = i,
53+
IntValue = i,
54+
LongValue = i,
55+
SByteValue = (sbyte)i,
56+
ShortValue = i,
57+
TimeSpanValue = new TimeSpan(i),
58+
UIntValue = i,
59+
ULongValue = i,
60+
UShortValue = i,
61+
GuidValue = Guid.NewGuid(),
62+
};
63+
}
64+
}
65+
66+
public class JsonSerializationBenchmarks
67+
{
68+
static ModelWithAllTypes allTypesModel = ModelWithAllTypes.Create(3);
69+
static ModelWithCommonTypes commonTypesModel = ModelWithCommonTypes.Create(3);
70+
static MemoryStream stream = new MemoryStream(32768);
71+
const string serializedString = "this is the test string";
72+
readonly string serializedString256 = new string('t', 256);
73+
readonly string serializedString512 = new string('t', 512);
74+
readonly string serializedString4096 = new string('t', 4096);
75+
76+
[Benchmark]
77+
public void SerializeJsonAllTypes()
78+
{
79+
string result = JsonSerializer.SerializeToString<ModelWithAllTypes>(allTypesModel);
80+
}
81+
82+
[Benchmark]
83+
public void SerializeJsonCommonTypes()
84+
{
85+
string result = JsonSerializer.SerializeToString<ModelWithCommonTypes>(commonTypesModel);
86+
}
87+
88+
[Benchmark]
89+
public void SerializeJsonString()
90+
{
91+
string result = JsonSerializer.SerializeToString<string>(serializedString);
92+
}
93+
94+
[Benchmark]
95+
public void SerializeJsonStringToStream()
96+
{
97+
stream.Position = 0;
98+
JsonSerializer.SerializeToStream<string>(serializedString, stream);
99+
}
100+
101+
[Benchmark]
102+
public void SerializeJsonString256ToStream()
103+
{
104+
stream.Position = 0;
105+
JsonSerializer.SerializeToStream<string>(serializedString256, stream);
106+
}
107+
108+
[Benchmark]
109+
public void SerializeJsonString512ToStream()
110+
{
111+
stream.Position = 0;
112+
JsonSerializer.SerializeToStream<string>(serializedString512, stream);
113+
}
114+
115+
[Benchmark]
116+
public void SerializeJsonString4096ToStream()
117+
{
118+
stream.Position = 0;
119+
JsonSerializer.SerializeToStream<string>(serializedString4096, stream);
120+
}
121+
122+
[Benchmark]
123+
public void SerializeJsonStringToStreamDirectly()
124+
{
125+
stream.Position = 0;
126+
string tmp = JsonSerializer.SerializeToString<string>(serializedString);
127+
byte[] arr = Encoding.UTF8.GetBytes(tmp);
128+
stream.Write(arr, 0, arr.Length);
129+
}
130+
131+
132+
[Benchmark]
133+
public void SerializeJsonAllTypesToStream()
134+
{
135+
stream.Position = 0;
136+
JsonSerializer.SerializeToStream<ModelWithAllTypes>(allTypesModel, stream);
137+
}
138+
139+
[Benchmark]
140+
public void SerializeJsonCommonTypesToStream()
141+
{
142+
stream.Position = 0;
143+
JsonSerializer.SerializeToStream<ModelWithCommonTypes>(commonTypesModel, stream);
144+
}
145+
146+
[Benchmark]
147+
public void SerializeJsonStringToStreamUsingDirectStreamWriter()
148+
{
149+
stream.Position = 0;
150+
var writer = new DirectStreamWriter(stream, JsonSerializer.UTF8Encoding);
151+
JsonWriter<string>.WriteRootObject(writer, serializedString);
152+
writer.Flush();
153+
}
154+
155+
[Benchmark]
156+
public void SerializeJsonString256ToStreamUsingDirectStreamWriter()
157+
{
158+
stream.Position = 0;
159+
var writer = new DirectStreamWriter(stream, JsonSerializer.UTF8Encoding);
160+
JsonWriter<string>.WriteRootObject(writer, serializedString256);
161+
writer.Flush();
162+
}
163+
164+
[Benchmark]
165+
public void SerializeJsonString512ToStreamUsingDirectStreamWriter()
166+
{
167+
stream.Position = 0;
168+
var writer = new DirectStreamWriter(stream, JsonSerializer.UTF8Encoding);
169+
JsonWriter<string>.WriteRootObject(writer, serializedString512);
170+
writer.Flush();
171+
}
172+
173+
[Benchmark]
174+
public void SerializeJsonString4096ToStreamUsingDirectStreamWriter()
175+
{
176+
stream.Position = 0;
177+
var writer = new DirectStreamWriter(stream, JsonSerializer.UTF8Encoding);
178+
JsonWriter<string>.WriteRootObject(writer, serializedString4096);
179+
writer.Flush();
180+
}
181+
}
182+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using BenchmarkDotNet.Configs;
3+
using BenchmarkDotNet.Jobs;
4+
using BenchmarkDotNet.Running;
5+
using BenchmarkDotNet.Validators;
6+
7+
namespace ServiceStack.Text.Benchmarks
8+
{
9+
public class Program
10+
{
11+
public static void Main(string[] args)
12+
{
13+
Console.WriteLine("Hello World!");
14+
BenchmarkRunner.Run<JsonSerializationBenchmarks>(
15+
ManualConfig
16+
.Create(DefaultConfig.Instance)
17+
//.With(Job.RyuJitX64)
18+
.With(Job.Core)
19+
.With(new BenchmarkDotNet.Diagnosers.CompositeDiagnoser())
20+
.With(ExecutionValidator.FailOnError)
21+
);
22+
}
23+
}
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"buildOptions": {
3+
"debugType": "portable",
4+
"emitEntryPoint": true
5+
},
6+
"dependencies": {
7+
"ServiceStack.Text": "1.0.*",
8+
"ServiceStack.Text.Tests": "1.0.*"
9+
},
10+
"frameworks": {
11+
"netcoreapp1.1": {
12+
"dependencies": {
13+
"Microsoft.NETCore.App": {
14+
"type": "platform",
15+
"version": "1.1.0"
16+
},
17+
"BenchmarkDotNet": "0.10.1"
18+
},
19+
"imports": "dnxcore50"
20+
}
21+
},
22+
"version": "1.0.0-*"
23+
}

global.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"projects": [
33
"src",
4-
"tests"
4+
"tests",
5+
"benchmarks"
56
],
67
"sdk": {
78
"version": "1.0.0-preview2-1-003177"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.IO;
3+
using System.Text;
4+
5+
namespace ServiceStack.Text
6+
{
7+
public class DirectStreamWriter : TextWriter
8+
{
9+
private const int optimizedBufferLength = 256;
10+
private const int maxBufferLength = 1024;
11+
12+
private Stream stream;
13+
private StreamWriter writer = null;
14+
private byte[] curChar = new byte[1];
15+
private bool needFlush = false;
16+
17+
private Encoding encoding;
18+
public override Encoding Encoding => encoding;
19+
20+
public DirectStreamWriter(Stream stream, Encoding encoding)
21+
{
22+
this.stream = stream;
23+
this.encoding = encoding;
24+
}
25+
26+
public override void Write(string s)
27+
{
28+
if (s.Length <= optimizedBufferLength)
29+
{
30+
if (needFlush)
31+
{
32+
writer.Flush();
33+
needFlush = false;
34+
}
35+
36+
byte[] buffer = Encoding.GetBytes(s);
37+
stream.Write(buffer, 0, buffer.Length);
38+
} else
39+
{
40+
if (writer == null)
41+
writer = new StreamWriter(stream, Encoding, s.Length < maxBufferLength ? s.Length : maxBufferLength);
42+
43+
writer.Write(s);
44+
needFlush = true;
45+
}
46+
}
47+
48+
public override void Write(char c)
49+
{
50+
if ((int)c < 128)
51+
{
52+
if (needFlush)
53+
{
54+
writer.Flush();
55+
needFlush = false;
56+
}
57+
58+
curChar[0] = (byte)c;
59+
stream.Write(curChar, 0, 1);
60+
} else
61+
{
62+
if (writer == null)
63+
writer = new StreamWriter(stream, Encoding, optimizedBufferLength);
64+
65+
writer.Write(c);
66+
needFlush = true;
67+
}
68+
}
69+
70+
public override void Flush()
71+
{
72+
if (writer != null)
73+
{
74+
writer.Flush();
75+
}
76+
else
77+
{
78+
stream.Flush();
79+
}
80+
}
81+
}
82+
}

src/ServiceStack.Text/JsonSerializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ public static void SerializeToStream<T>(T value, Stream stream)
147147
}
148148
else
149149
{
150-
var writer = new StreamWriter(stream, UTF8Encoding);
150+
var writer = new DirectStreamWriter(stream, UTF8Encoding);
151151
JsonWriter<T>.WriteRootObject(writer, value);
152152
writer.Flush();
153153
}
154154
}
155155

156156
public static void SerializeToStream(object value, Type type, Stream stream)
157157
{
158-
var writer = new StreamWriter(stream, UTF8Encoding);
158+
var writer = new DirectStreamWriter(stream, UTF8Encoding);
159159
JsonWriter.GetWriteFn(type)(writer, value);
160160
writer.Flush();
161161
}

src/ServiceStack.Text/ServiceStack.Text.Android.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@
141141
<Compile Include="DateTimeExtensions.cs">
142142
<SubType>Code</SubType>
143143
</Compile>
144+
<Compile Include="DirectStreamWriter.cs">
145+
<SubType>Code</SubType>
146+
</Compile>
144147
<Compile Include="CsvAttribute.cs" />
145148
<Compile Include="Env.cs">
146149
<SubType>Code</SubType>

src/ServiceStack.Text/ServiceStack.Text.AndroidIndie.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@
139139
<Compile Include="DateTimeExtensions.cs">
140140
<SubType>Code</SubType>
141141
</Compile>
142+
<Compile Include="DirectStreamWriter.cs">
143+
<SubType>Code</SubType>
144+
</Compile>
142145
<Compile Include="CsvAttribute.cs" />
143146
<Compile Include="Env.cs">
144147
<SubType>Code</SubType>

src/ServiceStack.Text/ServiceStack.Text.PCL.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@
134134
<Compile Include="DateTimeExtensions.cs">
135135
<SubType>Code</SubType>
136136
</Compile>
137+
<Compile Include="DirectStreamWriter.cs">
138+
<SubType>Code</SubType>
139+
</Compile>
137140
<Compile Include="CsvAttribute.cs" />
138141
<Compile Include="Env.cs">
139142
<SubType>Code</SubType>

src/ServiceStack.Text/ServiceStack.Text.SL5.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@
157157
<Compile Include="DateTimeExtensions.cs">
158158
<SubType>Code</SubType>
159159
</Compile>
160+
<Compile Include="DirectStreamWriter.cs">
161+
<SubType>Code</SubType>
162+
</Compile>
160163
<Compile Include="CsvAttribute.cs" />
161164
<Compile Include="Env.cs">
162165
<SubType>Code</SubType>

0 commit comments

Comments
 (0)