From 73187dde1e40bcfefac0254c4b733cd211c47d52 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 30 Mar 2013 16:59:08 +1300 Subject: [PATCH] -Performance --- .../JsonTextReaderTest.cs | 38 +++++++++++++++++++ Src/Newtonsoft.Json/JsonTextReader.cs | 4 +- Src/Newtonsoft.Json/Utilities/ConvertUtils.cs | 35 +++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index 44ab36e9..e4bf2e15 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -1110,6 +1110,44 @@ bye", reader.Value); } } + [Test] + public void ParseIntegers() + { + JsonTextReader reader = null; + + reader = new JsonTextReader(new StringReader("1")); + Assert.AreEqual(1, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("-1")); + Assert.AreEqual(-1, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("0")); + Assert.AreEqual(0, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("-0")); + Assert.AreEqual(0, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(int.MaxValue.ToString())); + Assert.AreEqual(int.MaxValue, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(int.MinValue.ToString())); + Assert.AreEqual(int.MinValue, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(long.MaxValue.ToString())); + + reader = new JsonTextReader(new StringReader("1E-06")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("1.1")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("")); + Assert.AreEqual(null, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("-")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + } + [Test] public void WriteReadWrite() { diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs index 0aeb69ae..d4c2840f 100644 --- a/Src/Newtonsoft.Json/JsonTextReader.cs +++ b/Src/Newtonsoft.Json/JsonTextReader.cs @@ -1185,9 +1185,7 @@ namespace Newtonsoft.Json } else { - string number = _stringReference.ToString(); - - numberValue = Convert.ToInt32(number, CultureInfo.InvariantCulture); + numberValue = ConvertUtils.IntParseFast(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); } numberType = JsonToken.Integer; diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs index 5e721104..8dd01558 100644 --- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs @@ -563,5 +563,40 @@ namespace Newtonsoft.Json.Utilities return false; } } + + public static int IntParseFast(char[] value, int start, int length) + { + if (length == 0) + throw new FormatException("Input string was not in a correct format."); + + bool isNegative = (value[start] == '-'); + + if (isNegative) + { + // just a negative sign + if (length == 1) + throw new FormatException("Input string was not in a correct format."); + + start++; + length--; + } + + int result = 0; + int end = start + length; + for (int i = start; i < end; i++) + { + char c = value[i]; + + if (!(c >= '0' && c <= '9')) + throw new FormatException("Input string was not in a correct format."); + + result = 10 * result + (c - 48); + } + + if (isNegative) + result = 0 - result; + + return result; + } } }