Performance optimization for integer value serialization. (#1544)
* Performance optimization for integer serialization. * Add int32 overloads for integer formatter. * fix parameter name * Prefer using the faster, 32 bit division code path, when possible. * fix code formatting * fix uint range check, add test coverage
This commit is contained in:
committed by
James Newton-King
parent
a8245a5b9e
commit
3ea750d6d6
@@ -45,6 +45,20 @@ namespace Newtonsoft.Json.Tests.Benchmarks
|
||||
|
||||
return sw.ToString();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public string SerializeIntegers()
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
JsonTextWriter jsonTextWriter = new JsonTextWriter(sw);
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
jsonTextWriter.WriteValue(i);
|
||||
}
|
||||
jsonTextWriter.Flush();
|
||||
|
||||
return sw.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -902,6 +902,9 @@ namespace Newtonsoft.Json.Tests
|
||||
jsonWriter.WriteValue(long.MinValue);
|
||||
jsonWriter.WriteValue(ulong.MaxValue);
|
||||
jsonWriter.WriteValue(ulong.MinValue);
|
||||
jsonWriter.WriteValue((ulong)uint.MaxValue - 1);
|
||||
jsonWriter.WriteValue((ulong)uint.MaxValue);
|
||||
jsonWriter.WriteValue((ulong)uint.MaxValue + 1);
|
||||
|
||||
jsonWriter.WriteEndArray();
|
||||
}
|
||||
@@ -918,7 +921,10 @@ namespace Newtonsoft.Json.Tests
|
||||
9223372036854775807,
|
||||
-9223372036854775808,
|
||||
18446744073709551615,
|
||||
0
|
||||
0,
|
||||
4294967294,
|
||||
4294967295,
|
||||
4294967296
|
||||
]", sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -817,20 +817,77 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIntegerValue(ulong uvalue, bool negative)
|
||||
private void WriteIntegerValue(ulong value, bool negative)
|
||||
{
|
||||
if (!negative & uvalue <= 9)
|
||||
if (!negative & value <= 9)
|
||||
{
|
||||
_writer.Write((char)('0' + uvalue));
|
||||
_writer.Write((char)('0' + value));
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = WriteNumberToBuffer(uvalue, negative);
|
||||
int length = WriteNumberToBuffer(value, negative);
|
||||
_writer.Write(_writeBuffer, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
private int WriteNumberToBuffer(ulong value, bool negative)
|
||||
{
|
||||
if (value <= uint.MaxValue)
|
||||
{
|
||||
// avoid the 64 bit division if possible
|
||||
return WriteNumberToBuffer((uint)value, negative);
|
||||
}
|
||||
|
||||
EnsureWriteBuffer();
|
||||
|
||||
int totalLength = MathUtils.IntLength(value);
|
||||
|
||||
if (negative)
|
||||
{
|
||||
totalLength++;
|
||||
_writeBuffer[0] = '-';
|
||||
}
|
||||
|
||||
int index = totalLength;
|
||||
|
||||
do
|
||||
{
|
||||
ulong quotient = value / 10;
|
||||
ulong digit = value - (quotient * 10);
|
||||
_writeBuffer[--index] = (char)('0' + digit);
|
||||
value = quotient;
|
||||
} while (value != 0);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
private void WriteIntegerValue(int value)
|
||||
{
|
||||
if (value >= 0 && value <= 9)
|
||||
{
|
||||
_writer.Write((char)('0' + value));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool negative = value < 0;
|
||||
WriteIntegerValue(negative ? (uint)-value : (uint)value, negative);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIntegerValue(uint value, bool negative)
|
||||
{
|
||||
if (!negative & value <= 9)
|
||||
{
|
||||
_writer.Write((char)('0' + value));
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = WriteNumberToBuffer(value, negative);
|
||||
_writer.Write(_writeBuffer, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
private int WriteNumberToBuffer(uint value, bool negative)
|
||||
{
|
||||
EnsureWriteBuffer();
|
||||
|
||||
@@ -846,8 +903,10 @@ namespace Newtonsoft.Json
|
||||
|
||||
do
|
||||
{
|
||||
_writeBuffer[--index] = (char)('0' + value % 10);
|
||||
value /= 10;
|
||||
uint quotient = value / 10;
|
||||
uint digit = value - (quotient * 10);
|
||||
_writeBuffer[--index] = (char)('0' + digit);
|
||||
value = quotient;
|
||||
} while (value != 0);
|
||||
|
||||
return totalLength;
|
||||
|
||||
Reference in New Issue
Block a user