Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S.IO.StringReader: Use ReadOnlySpan.IndexOfAny in ReadLine() for performance #60463

Merged
Merged
49 changes: 24 additions & 25 deletions src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Threading;
using System.Threading.Tasks;
using Internal.Runtime.CompilerServices;

namespace System.IO
{
Expand Down Expand Up @@ -46,7 +47,7 @@ public override int Peek()
{
if (_s == null)
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}
if (_pos == _length)
{
Expand All @@ -63,7 +64,7 @@ public override int Read()
{
if (_s == null)
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}
if (_pos == _length)
{
Expand Down Expand Up @@ -98,7 +99,7 @@ public override int Read(char[] buffer, int index, int count)
}
if (_s == null)
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}

int n = _length - _pos;
Expand Down Expand Up @@ -126,7 +127,7 @@ public override int Read(Span<char> buffer)

if (_s == null)
nietras marked this conversation as resolved.
Show resolved Hide resolved
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}

int n = _length - _pos;
Expand All @@ -150,7 +151,7 @@ public override string ReadToEnd()
{
if (_s == null)
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}

string s;
Expand All @@ -177,36 +178,34 @@ public override string ReadToEnd()
{
if (_s == null)
nietras marked this conversation as resolved.
Show resolved Hide resolved
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
ThrowHelper.ThrowObjectDisposedException_ReaderClosed();
}
if ((uint)_pos >= (uint)_length)
nietras marked this conversation as resolved.
Show resolved Hide resolved
return null;

int i = _pos;
while (i < _length)
ReadOnlySpan<char> remaining = _s.AsSpan(_pos);
int foundLineLength = remaining.IndexOfAny('\r', '\n');
if (foundLineLength >= 0)
{
char ch = _s[i];
if (ch == '\r' || ch == '\n')
string result = foundLineLength == 0
nietras marked this conversation as resolved.
Show resolved Hide resolved
? string.Empty
: new string(new ReadOnlySpan<char>(ref Unsafe.AsRef(remaining.GetPinnableReference()), foundLineLength)); //_s.Substring(_pos, foundLineLength);
nietras marked this conversation as resolved.
Show resolved Hide resolved

char ch = remaining[foundLineLength];
_pos += foundLineLength + 1;
if (ch == '\r' && _pos < _length && _s[_pos] == '\n')
{
string result = _s.Substring(_pos, i - _pos);
_pos = i + 1;
if (ch == '\r' && _pos < _length && _s[_pos] == '\n')
{
_pos++;
}

return result;
_pos++;
}

i++;
return result;
}

if (i > _pos)
else
{
string result = _s.Substring(_pos, i - _pos);
_pos = i;
string result = new string(remaining); // _s.Substring(_pos, _length - _pos);
_pos = _length;
return result;
}

return null;
}

#region Task based Async APIs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,12 @@ internal static void ThrowObjectDisposedException_FileClosed()
throw new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed);
}

[DoesNotReturn]
internal static void ThrowObjectDisposedException_ReaderClosed()
nietras marked this conversation as resolved.
Show resolved Hide resolved
{
throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
}

[DoesNotReturn]
internal static void ThrowObjectDisposedException(ExceptionResource resource)
{
Expand Down