Skip to content

Commit 004f641

Browse files
committed
Peformance: Utilize compiler hints.
1 parent 14a5129 commit 004f641

File tree

5 files changed

+162
-141
lines changed

5 files changed

+162
-141
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Future
2+
- Improved tokenization performance by allowing and forcing more aggresive inlining.
3+
- In my benchmark, this is about 8 to 9% faster
4+
15
# 1.3.0
26
- Removed net5 support and added net7 support
37

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Globalization;
2+
3+
namespace PhpSerializerNET;
4+
5+
internal static class StringExtensions {
6+
internal static double PhpToDouble(this string value) {
7+
return value switch {
8+
"INF" => double.PositiveInfinity,
9+
"-INF" => double.NegativeInfinity,
10+
"NAN" => double.NaN,
11+
_ => double.Parse(value, CultureInfo.InvariantCulture),
12+
};
13+
}
14+
15+
internal static bool PhpToBool(this string value) => value == "1";
16+
17+
internal static long PhpToLong(this string value) => long.Parse(value, CultureInfo.InvariantCulture);
18+
}

PhpSerializerNET/PhpDeserializer.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ public static void ClearPropertyInfoCache() {
5656
private object DeserializeToken(PhpSerializeToken token) {
5757
switch (token.Type) {
5858
case PhpSerializerType.Boolean:
59-
return token.ToBool();
59+
return token.Value.PhpToBool();
6060
case PhpSerializerType.Integer:
61-
return token.ToLong();
61+
return token.Value.PhpToLong();
6262
case PhpSerializerType.Floating:
63-
return token.ToDouble();
63+
return token.Value.PhpToDouble();
6464
case PhpSerializerType.String:
6565
if (this._options.NumberStringToBool && (token.Value == "0" || token.Value == "1")) {
66-
return token.ToBool();
66+
return token.Value.PhpToBool();
6767
}
6868
return token.Value;
6969
case PhpSerializerType.Array:
@@ -173,7 +173,7 @@ private object DeserializeInteger(Type targetType, PhpSerializeToken token) {
173173

174174
private object DeserializeDouble(Type targetType, PhpSerializeToken token) {
175175
if (targetType == typeof(double) || targetType == typeof(float)) {
176-
return token.ToDouble();
176+
return token.Value.PhpToDouble();
177177
}
178178

179179
token.Value = token.Value switch {
@@ -186,15 +186,15 @@ private object DeserializeDouble(Type targetType, PhpSerializeToken token) {
186186

187187
private static object DeserializeBoolean(Type targetType, PhpSerializeToken token) {
188188
if (targetType == typeof(bool) || targetType == typeof(bool?)) {
189-
return token.ToBool();
189+
return token.Value.PhpToBool();
190190
}
191191
Type underlyingType = targetType;
192192
if (targetType.IsNullableReferenceType()) {
193193
underlyingType = targetType.GenericTypeArguments[0];
194194
}
195195

196196
if (underlyingType.IsIConvertible()) {
197-
return ((IConvertible)token.ToBool()).ToType(underlyingType, CultureInfo.InvariantCulture);
197+
return ((IConvertible)token.Value.PhpToBool()).ToType(underlyingType, CultureInfo.InvariantCulture);
198198
} else {
199199
throw new DeserializationException(
200200
$"Can not assign value \"{token.Value}\" (at position {token.Position}) to target type of {targetType.Name}."
@@ -250,7 +250,7 @@ private object DeserializeTokenFromSimpleType(Type givenType, PhpSerializeToken
250250

251251
if (targetType == typeof(bool)) {
252252
if (_options.NumberStringToBool && token.Value is "0" or "1") {
253-
return token.ToBool();
253+
return token.Value.PhpToBool();
254254
}
255255
}
256256

@@ -319,7 +319,7 @@ private object MakeObject(Type targetType, PhpSerializeToken token) {
319319
if (token.Children[i].Type == PhpSerializerType.String) {
320320
propertyName = this._options.CaseSensitiveProperties ? token.Children[i].Value : token.Children[i].Value.ToLower();
321321
} else if (token.Children[i].Type == PhpSerializerType.Integer) {
322-
propertyName = token.Children[i].ToLong();
322+
propertyName = token.Children[i].Value.PhpToLong();
323323
} else {
324324
throw new DeserializationException(
325325
$"Error encountered deserizalizing an object of type '{targetType.FullName}': " +
@@ -450,7 +450,7 @@ private object MakeCollection(PhpSerializeToken token) {
450450
isList = false;
451451
break;
452452
} else {
453-
var key = token.Children[i].ToLong();
453+
var key = token.Children[i].Value.PhpToLong();
454454
if (i == 0 || key == previousKey + 1) {
455455
previousKey = key;
456456
} else {

PhpSerializerNET/PhpSerializeToken.cs

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,14 @@ This Source Code Form is subject to the terms of the Mozilla Public
33
License, v. 2.0. If a copy of the MPL was not distributed with this
44
file, You can obtain one at http://mozilla.org/MPL/2.0/.
55
**/
6-
7-
using System.Globalization;
8-
96
namespace PhpSerializerNET;
107

118
/// <summary>
129
/// PHP Serialization format token. Holds type, length, position (of the token in the input string) and child information.
1310
/// </summary>
14-
internal struct PhpSerializeToken {
15-
internal PhpSerializerType Type;
16-
internal string Value;
17-
18-
internal PhpSerializeToken[] Children;
19-
internal int Position;
20-
21-
/// <summary>
22-
/// Convert the token value to a <see cref="long"/>.
23-
/// </summary>
24-
/// <returns>
25-
/// The token value as a <see cref="long"/>.
26-
/// </returns>
27-
internal long ToLong() {
28-
return long.Parse(this.Value, CultureInfo.InvariantCulture);
29-
}
30-
31-
/// <summary>
32-
/// Convert the token value to a <see cref="double"/>.
33-
/// </summary>
34-
/// <returns>
35-
/// The token value as a <see cref="double"/>.
36-
/// </returns>
37-
internal double ToDouble() {
38-
return this.Value switch {
39-
"INF" => double.PositiveInfinity,
40-
"-INF" => double.NegativeInfinity,
41-
"NAN" => double.NaN,
42-
_ => double.Parse(this.Value, CultureInfo.InvariantCulture),
43-
};
44-
;
45-
}
46-
47-
/// <summary>
48-
/// Convert the token value to a <see cref="bool"/>
49-
/// </summary>
50-
/// <returns>
51-
/// The token value as a <see cref="bool"/>
52-
/// </returns>
53-
internal bool ToBool() {
54-
return this.Value == "1";
55-
}
56-
}
11+
internal record struct PhpSerializeToken(
12+
PhpSerializerType Type,
13+
int Position,
14+
string Value,
15+
PhpSerializeToken[] Children
16+
);

0 commit comments

Comments
 (0)