From fac8514ff62da35a128a3fd8f2372635c99768e0 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Thu, 1 Nov 2012 20:14:08 +1300 Subject: [PATCH] -Performance --- Src/Newtonsoft.Json/JsonPosition.cs | 42 +++++++-------- Src/Newtonsoft.Json/JsonReader.cs | 18 ++++--- Src/Newtonsoft.Json/JsonWriter.cs | 79 ++++++++++------------------- 3 files changed, 55 insertions(+), 84 deletions(-) diff --git a/Src/Newtonsoft.Json/JsonPosition.cs b/Src/Newtonsoft.Json/JsonPosition.cs index 8f48c8ec..57ac43aa 100644 --- a/Src/Newtonsoft.Json/JsonPosition.cs +++ b/Src/Newtonsoft.Json/JsonPosition.cs @@ -39,45 +39,39 @@ namespace Newtonsoft.Json internal struct JsonPosition { internal JsonContainerType Type; - internal int? Position; + internal int Position; internal string PropertyName; + internal bool HasIndex; + + public JsonPosition(JsonContainerType type) + { + Type = type; + HasIndex = TypeHasIndex(type); + Position = -1; + PropertyName = null; + } internal void WriteTo(StringBuilder sb) { switch (Type) { case JsonContainerType.Object: - if (PropertyName != null) - { - if (sb.Length > 0) - sb.Append("."); - sb.Append(PropertyName); - } + if (sb.Length > 0) + sb.Append("."); + sb.Append(PropertyName); break; case JsonContainerType.Array: case JsonContainerType.Constructor: - if (Position != null) - { - sb.Append("["); - sb.Append(Position); - sb.Append("]"); - } + sb.Append("["); + sb.Append(Position); + sb.Append("]"); break; } } - internal bool InsideContainer() + internal static bool TypeHasIndex(JsonContainerType type) { - switch (Type) - { - case JsonContainerType.Object: - return (PropertyName != null); - case JsonContainerType.Array: - case JsonContainerType.Constructor: - return (Position != null); - } - - return false; + return (type == JsonContainerType.Array || type == JsonContainerType.Constructor); } internal static string BuildPath(IEnumerable positions) diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index 6bfd3964..1e4ab185 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -225,7 +225,15 @@ namespace Newtonsoft.Json if (_currentPosition.Type == JsonContainerType.None) return string.Empty; - return JsonPosition.BuildPath(_stack.Concat(new[] { _currentPosition })); + bool insideContainer = (_currentState != State.ArrayStart + && _currentState != State.ConstructorStart + && _currentState != State.ObjectStart); + + IEnumerable positions = (!insideContainer) + ? _stack + : _stack.Concat(new[] {_currentPosition}); + + return JsonPosition.BuildPath(positions); } } @@ -265,16 +273,12 @@ namespace Newtonsoft.Json if (_currentPosition.Type == JsonContainerType.None) { - _currentPosition.Type = value; + _currentPosition = new JsonPosition(value); } else { _stack.Add(_currentPosition); - JsonPosition state = new JsonPosition - { - Type = value - }; - _currentPosition = state; + _currentPosition = new JsonPosition(value); // this is a little hacky because Depth increases when first property/value is written but only testing here is faster/simpler if (_maxDepth != null && Depth + 1 > _maxDepth && !_hasExceededMaxDepth) diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs index 583d73d9..24829505 100644 --- a/Src/Newtonsoft.Json/JsonWriter.cs +++ b/Src/Newtonsoft.Json/JsonWriter.cs @@ -142,21 +142,6 @@ namespace Newtonsoft.Json return depth; } } - - internal string ContainerPath - { - get - { - if (_currentPosition.Type == JsonContainerType.None) - return string.Empty; - - IEnumerable positions = (_currentPosition.InsideContainer()) - ? _stack - : _stack.Concat(new[] { _currentPosition }); - - return JsonPosition.BuildPath(positions); - } - } /// /// Gets the state of the writer. @@ -190,6 +175,17 @@ namespace Newtonsoft.Json } } + internal string ContainerPath + { + get + { + if (_currentPosition.Type == JsonContainerType.None) + return string.Empty; + + return JsonPosition.BuildPath(_stack); + } + } + /// /// Gets the path of the writer. /// @@ -200,7 +196,15 @@ namespace Newtonsoft.Json if (_currentPosition.Type == JsonContainerType.None) return string.Empty; - return JsonPosition.BuildPath(_stack.Concat(new[] { _currentPosition })); + bool insideContainer = (_currentState != State.ArrayStart + && _currentState != State.ConstructorStart + && _currentState != State.ObjectStart); + + IEnumerable positions = (!insideContainer) + ? _stack + : _stack.Concat(new[] { _currentPosition }); + + return JsonPosition.BuildPath(positions); } } @@ -249,45 +253,29 @@ namespace Newtonsoft.Json internal void UpdateScopeWithFinishedValue() { - if (_currentPosition.Type == JsonContainerType.Array - || _currentPosition.Type == JsonContainerType.Constructor) - { - if (_currentPosition.Position == null) - _currentPosition.Position = 0; - else + if (_currentPosition.HasIndex) _currentPosition.Position++; - } } private void Push(JsonContainerType value) { - if (_currentPosition.Type == JsonContainerType.None) - { - _currentPosition.Type = value; - } - else - { + if (_currentPosition.Type != JsonContainerType.None) _stack.Add(_currentPosition); - var state = new JsonPosition - { - Type = value - }; - _currentPosition = state; - } + + _currentPosition = new JsonPosition(value); } private JsonContainerType Pop() { - JsonPosition oldPosition; + JsonPosition oldPosition = _currentPosition; + if (_stack.Count > 0) { - oldPosition = _currentPosition; _currentPosition = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); } else { - oldPosition = _currentPosition; _currentPosition = new JsonPosition(); } @@ -564,21 +552,6 @@ namespace Newtonsoft.Json } } - private JsonContainerType GetTypeForCloseToken(JsonToken token) - { - switch (token) - { - case JsonToken.EndObject: - return JsonContainerType.Object; - case JsonToken.EndArray: - return JsonContainerType.Array; - case JsonToken.EndConstructor: - return JsonContainerType.Constructor; - default: - throw JsonWriterException.Create(this, "No type for token: " + token, null); - } - } - private JsonToken GetCloseTokenForType(JsonContainerType type) { switch (type)