Skip to content

Commit

Permalink
Revert changes to WriteEscapedJsonStringValueAsync due to degraded perf
Browse files Browse the repository at this point in the history
  • Loading branch information
gathogojr committed Aug 18, 2022
1 parent 4b3fa4c commit 622c172
Showing 1 changed file with 32 additions and 39 deletions.
71 changes: 32 additions & 39 deletions src/Microsoft.OData.Core/Json/JsonValueUtilsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ internal static async Task WriteEscapedJsonStringAsync(
/// <param name="stringEscapeOption">The string escape option.</param>
/// <param name="buffer">Char buffer to use for streaming data.</param>
/// <param name="bufferPool">Array pool for renting a buffer.</param>
internal static Task WriteEscapedJsonStringValueAsync(
internal static async Task WriteEscapedJsonStringValueAsync(
this TextWriter writer,
string inputString,
ODataStringEscapeOption stringEscapeOption,
Expand All @@ -394,53 +394,46 @@ internal static Task WriteEscapedJsonStringValueAsync(
int firstIndex;
if (!CheckIfStringHasSpecialChars(inputString, stringEscapeOption, out firstIndex))
{
// This block is executed majority of the times
// Eliding async and await for better performance and memory usage metrics
return writer.WriteAsync(inputString);
await writer.WriteAsync(inputString).ConfigureAwait(false);
}
else
{
return WriteEscapedJsonStringValueInnerAsync();

async Task WriteEscapedJsonStringValueInnerAsync()
Debug.Assert(firstIndex < inputString.Length, "First index of the special character should be within the string");
buffer.Value = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer.Value);
int bufferLength = buffer.Value.Length;
int bufferIndex = 0;
int currentIndex = 0;

// Let's copy and flush strings up to the first index of the special char
while (currentIndex < firstIndex)
{
Debug.Assert(firstIndex < inputString.Length, "First index of the special character should be within the string");
buffer.Value = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer.Value);
int bufferLength = buffer.Value.Length;
int bufferIndex = 0;
int currentIndex = 0;

// Let's copy and flush strings up to the first index of the special char
while (currentIndex < firstIndex)
{
int substrLength = firstIndex - currentIndex;

Debug.Assert(substrLength > 0, "SubStrLength should be greater than 0 always");

// If the first index of the special character is larger than the buffer length,
// flush everything to the buffer first and reset the buffer to the next chunk.
// Otherwise copy to the buffer and go on from there.
if (substrLength >= bufferLength)
{
inputString.CopyTo(currentIndex, buffer.Value, 0, bufferLength);
await writer.WriteAsync(buffer.Value, 0, bufferLength).ConfigureAwait(false);
currentIndex += bufferLength;
}
else
{
WriteSubstringToBuffer(inputString, ref currentIndex, buffer.Value, ref bufferIndex, substrLength);
}
}
int substrLength = firstIndex - currentIndex;

// Write escaped string to buffer
WriteEscapedStringToBuffer(writer, inputString, ref currentIndex, buffer.Value, ref bufferIndex, stringEscapeOption);
Debug.Assert(substrLength > 0, "SubStrLength should be greater than 0 always");

// write any remaining chars to the writer
if (bufferIndex > 0)
// If the first index of the special character is larger than the buffer length,
// flush everything to the buffer first and reset the buffer to the next chunk.
// Otherwise copy to the buffer and go on from there.
if (substrLength >= bufferLength)
{
inputString.CopyTo(currentIndex, buffer.Value, 0, bufferLength);
await writer.WriteAsync(buffer.Value, 0, bufferLength).ConfigureAwait(false);
currentIndex += bufferLength;
}
else
{
await writer.WriteAsync(buffer.Value, 0, bufferIndex).ConfigureAwait(false);
WriteSubstringToBuffer(inputString, ref currentIndex, buffer.Value, ref bufferIndex, substrLength);
}
}

// Write escaped string to buffer
WriteEscapedStringToBuffer(writer, inputString, ref currentIndex, buffer.Value, ref bufferIndex, stringEscapeOption);

// write any remaining chars to the writer
if (bufferIndex > 0)
{
await writer.WriteAsync(buffer.Value, 0, bufferIndex).ConfigureAwait(false);
}
}
}

Expand Down

0 comments on commit 622c172

Please sign in to comment.