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

Commit f6951de

Browse files
committed
Optimizations tweaking
1 parent ec28f37 commit f6951de

File tree

2 files changed

+43
-26
lines changed

2 files changed

+43
-26
lines changed

src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ internal static object StringToType(
5959
Dictionary<HashedStringSegment, TypeAccessor> typeAccessorMap) =>
6060
StringToType(typeConfig, new StringSegment(strType), ctorFn, typeAccessorMap);
6161

62+
static readonly StringSegment typeAttr = new StringSegment(JsWriter.TypeAttr);
6263

6364
internal static object StringToType(
6465
TypeConfig typeConfig,
@@ -72,11 +73,16 @@ internal static object StringToType(
7273
if (!strType.HasValue)
7374
return null;
7475

76+
var buffer = strType.Buffer;
77+
var offset = strType.Offset;
78+
var strTypeLength = strType.Length;
79+
7580
//if (!Serializer.EatMapStartChar(strType, ref index))
76-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
77-
if (strType.GetChar(index++) != JsWriter.MapStartChar)
81+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
82+
if (buffer[offset + index] != JsWriter.MapStartChar)
7883
throw DeserializeTypeRef.CreateSerializationError(type, strType.Value);
7984

85+
index++;
8086
if (JsonTypeSerializer.IsEmptyMap(strType, index)) return ctorFn();
8187

8288
object instance = null;
@@ -85,21 +91,20 @@ internal static object StringToType(
8591
? ParseUtils.LenientPropertyNameResolver
8692
: ParseUtils.DefaultPropertyNameResolver;
8793

88-
var strTypeLength = strType.Length;
8994
while (index < strTypeLength)
9095
{
9196
var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index);
9297

9398
//Serializer.EatMapKeySeperator(strType, ref index);
94-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
95-
if (strType.Length != index) index++;
99+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
100+
if (strTypeLength != index) index++;
96101

97102
var propertyValueStr = Serializer.EatValue(strType, ref index);
98103
var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;
99104

100105
//if we already have an instance don't check type info, because then we will have a half deserialized object
101106
//we could throw here or just use the existing instance.
102-
if (instance == null && possibleTypeInfo && propertyName == new StringSegment(JsWriter.TypeAttr))
107+
if (instance == null && possibleTypeInfo && propertyName == typeAttr)
103108
{
104109
var explicitTypeName = Serializer.ParseString(propertyValueStr);
105110
var explicitType = JsConfig.TypeFinder(explicitTypeName);
@@ -165,13 +170,13 @@ internal static object StringToType(
165170
}
166171

167172
//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
168-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
169-
if (index != strType.Length)
173+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
174+
if (index != strTypeLength)
170175
{
171-
var success = strType.GetChar(index) == JsWriter.ItemSeperator || strType.GetChar(index) == JsWriter.MapEndChar;
176+
var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar;
172177
index++;
173178
if (success)
174-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
179+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
175180
}
176181

177182
continue;
@@ -208,13 +213,13 @@ internal static object StringToType(
208213
}
209214

210215
//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
211-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
216+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
212217
if (index != strType.Length)
213218
{
214-
var success = strType.GetChar(index) == JsWriter.ItemSeperator || strType.GetChar(index) == JsWriter.MapEndChar;
219+
var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar;
215220
index++;
216221
if (success)
217-
for (; index < strType.Length; index++) { var c = strType.GetChar(index); if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
222+
for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) break; } //Whitespace inline
218223
}
219224

220225
}

src/ServiceStack.Text/Json/JsonTypeSerializer.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -369,16 +369,20 @@ internal static string ParseString(string json, ref int index)
369369
internal static StringSegment ParseString(StringSegment json, ref int index)
370370
{
371371
var jsonLength = json.Length;
372-
if (json.GetChar(index) != JsonUtils.QuoteChar)
372+
var buffer = json.Buffer;
373+
var offset = json.Offset;
374+
375+
if (buffer[offset + index] != JsonUtils.QuoteChar)
373376
throw new Exception("Invalid unquoted string starting with: " + json.Value.SafeSubstring(50));
374377

375378
var startIndex = ++index;
376379
do
377380
{
378-
char c = json.GetChar(index);
381+
char c = buffer[offset + index];
379382
if (c == JsonUtils.QuoteChar) break;
380383
if (c != JsonUtils.EscapeChar) continue;
381-
c = json.GetChar(index++);
384+
c = buffer[offset + index];
385+
index++;
382386
if (c == 'u')
383387
{
384388
index += 4;
@@ -387,7 +391,7 @@ internal static StringSegment ParseString(StringSegment json, ref int index)
387391
if (index == jsonLength)
388392
throw new Exception("Invalid unquoted string ending with: " + json.Value.SafeSubstring(json.Length - 50, 50));
389393
index++;
390-
return json.Subsegment(startIndex, Math.Min(index, jsonLength) - startIndex - 1);
394+
return new StringSegment(buffer, offset + startIndex, Math.Min(index, jsonLength) - startIndex - 1);
391395
}
392396

393397
public string UnescapeString(string value)
@@ -435,8 +439,10 @@ private static StringSegment UnEscapeJsonString(StringSegment json, ref int inde
435439
{
436440
if (json.IsNullOrEmpty()) return json;
437441
var jsonLength = json.Length;
442+
var buffer = json.Buffer;
443+
var offset = json.Offset;
438444

439-
var firstChar = json.GetChar(index);
445+
var firstChar = buffer[offset + index];
440446
if (firstChar == JsonUtils.QuoteChar)
441447
{
442448
index++;
@@ -455,7 +461,7 @@ private static StringSegment UnEscapeJsonString(StringSegment json, ref int inde
455461
else
456462
{
457463
var strEndPos = json.IndexOfAny(IsSafeJsonChars, index);
458-
if (strEndPos == -1) return json.Subsegment(index, jsonLength - index);
464+
if (strEndPos == -1) return new StringSegment(buffer, offset + index, jsonLength - index);
459465
}
460466

461467
return Unescape(json);
@@ -708,7 +714,7 @@ public StringSegment EatValue(StringSegment value, ref int i)
708714
var offset = value.Offset;
709715
if (i == valueLength) return default(StringSegment);
710716

711-
for (; i < value.Length; i++) { var c = buf[offset + i]; if (!JsonUtils.IsWhiteSpace(c)) break; } //Whitespace inline
717+
while (i < valueLength && JsonUtils.IsWhiteSpace(buf[offset + i])) i++; //Whitespace inline
712718
if (i == valueLength) return default(StringSegment);
713719

714720
var tokenStartPos = i;
@@ -729,7 +735,7 @@ public StringSegment EatValue(StringSegment value, ref int i)
729735

730736
//Is Type/Map, i.e. {...}
731737
case JsWriter.MapStartChar:
732-
while (++i < valueLength && endsToEat > 0)
738+
while (++i < valueLength)
733739
{
734740
valueChar = buf[offset +i];
735741

@@ -748,14 +754,17 @@ public StringSegment EatValue(StringSegment value, ref int i)
748754
if (valueChar == JsWriter.MapStartChar)
749755
endsToEat++;
750756

751-
if (valueChar == JsWriter.MapEndChar)
752-
endsToEat--;
757+
if (valueChar == JsWriter.MapEndChar && --endsToEat == 0)
758+
{
759+
i++;
760+
break;
761+
}
753762
}
754763
return value.Subsegment(tokenStartPos, i - tokenStartPos);
755764

756765
//Is List, i.e. [...]
757766
case JsWriter.ListStartChar:
758-
while (++i < valueLength && endsToEat > 0)
767+
while (++i < valueLength)
759768
{
760769
valueChar = buf[offset + i];
761770

@@ -774,8 +783,11 @@ public StringSegment EatValue(StringSegment value, ref int i)
774783
if (valueChar == JsWriter.ListStartChar)
775784
endsToEat++;
776785

777-
if (valueChar == JsWriter.ListEndChar)
778-
endsToEat--;
786+
if (valueChar == JsWriter.ListEndChar && --endsToEat == 0)
787+
{
788+
i++;
789+
break;
790+
}
779791
}
780792
return value.Subsegment(tokenStartPos, i - tokenStartPos);
781793
}

0 commit comments

Comments
 (0)