Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
xtqqczze committed Dec 12, 2024
1 parent f30cfc0 commit 3401370
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 99 deletions.
13 changes: 6 additions & 7 deletions src/libraries/System.Private.CoreLib/src/System/BitConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -798,21 +798,20 @@ public static string ToString(byte[] value, int startIndex, int length)
// (int.MaxValue / 3) == 715,827,882 Bytes == 699 MB
ArgumentOutOfRangeException.ThrowIfGreaterThan(length, int.MaxValue / 3);

string result = string.FastAllocateString(length * 3 - 1);
string result = string.Alloc(length * 3 - 1, out Span<char> resultSpan);

var dst = new Span<char>(ref result.GetRawStringData(), result.Length);
var src = new ReadOnlySpan<byte>(value, startIndex, length);
int i = 0;
int j = 0;
byte b = src[i++];
dst[j++] = HexConverter.ToCharUpper(b >> 4);
dst[j++] = HexConverter.ToCharUpper(b);
resultSpan[j++] = HexConverter.ToCharUpper(b >> 4);
resultSpan[j++] = HexConverter.ToCharUpper(b);
while (i < src.Length)
{
b = src[i++];
dst[j++] = '-';
dst[j++] = HexConverter.ToCharUpper(b >> 4);
dst[j++] = HexConverter.ToCharUpper(b);
resultSpan[j++] = '-';
resultSpan[j++] = HexConverter.ToCharUpper(b >> 4);
resultSpan[j++] = HexConverter.ToCharUpper(b);
}

return result;
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2355,11 +2355,11 @@ public static string ToBase64String(ReadOnlySpan<byte> bytes, Base64FormattingOp
bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
int outputLength = ToBase64_CalculateAndValidateOutputLength(bytes.Length, insertLineBreaks);

string result = string.FastAllocateString(outputLength);
string result = string.Alloc(outputLength, out Span<char> resultSpan);

if (Vector128.IsHardwareAccelerated && !insertLineBreaks && bytes.Length >= Base64VectorizationLengthThreshold)
{
ToBase64CharsLargeNoLineBreaks(bytes, new Span<char>(ref result.GetRawStringData(), result.Length), result.Length);
ToBase64CharsLargeNoLineBreaks(bytes, resultSpan, result.Length);
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Enum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1945,8 +1945,8 @@ private static bool TryFormatPrimitiveNonDefault<TUnderlying, TStorage>(RuntimeT
foundItems = foundItems.Slice(0, foundItemsCount);
int length = GetMultipleEnumsFlagsFormatResultLength(resultLength, foundItemsCount);

result = string.FastAllocateString(length);
WriteMultipleFoundFlagsNames(names, foundItems, new Span<char>(ref result.GetRawStringData(), result.Length));
result = string.Alloc(length, out Span<char> resultSpan);
WriteMultipleFoundFlagsNames(names, foundItems, resultSpan);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/libraries/System.Private.CoreLib/src/System/Exception.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ public override string ToString()
}

// Create the string
string result = string.FastAllocateString(length);
Span<char> resultSpan = new Span<char>(ref result.GetRawStringData(), result.Length);
string result = string.Alloc(length, out Span<char> resultSpan);

// Fill it in
Write(className, ref resultSpan);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,8 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider

internal static string Format(DateTime dateTime, string? format, IFormatProvider? provider, TimeSpan offset)
{
string result;
Span<char> resultSpan;
DateTimeFormatInfo dtfi;

if (string.IsNullOrEmpty(format))
Expand All @@ -929,17 +931,17 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider
{
if (IsTimeOnlySpecialCase(dateTime, dtfi))
{
string str = string.FastAllocateString(FormatSLength);
TryFormatS(dateTime, new Span<char>(ref str.GetRawStringData(), str.Length), out int charsWritten);
result = string.Alloc(FormatSLength, out resultSpan);
TryFormatS(dateTime, resultSpan, out int charsWritten);
Debug.Assert(charsWritten == FormatSLength);
return str;
return result;
}
else if (ReferenceEquals(dtfi, DateTimeFormatInfo.InvariantInfo))
{
string str = string.FastAllocateString(FormatInvariantGMinLength);
TryFormatInvariantG(dateTime, offset, new Span<char>(ref str.GetRawStringData(), str.Length), out int charsWritten);
result = string.Alloc(FormatInvariantGMinLength, out resultSpan);
TryFormatInvariantG(dateTime, offset, resultSpan, out int charsWritten);
Debug.Assert(charsWritten == FormatInvariantGMinLength);
return str;
return result;
}
else
{
Expand All @@ -955,10 +957,10 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider
}
else if (ReferenceEquals(dtfi, DateTimeFormatInfo.InvariantInfo))
{
string str = string.FastAllocateString(FormatInvariantGMaxLength);
TryFormatInvariantG(dateTime, offset, new Span<char>(ref str.GetRawStringData(), str.Length), out int charsWritten);
result = string.Alloc(FormatInvariantGMaxLength, out resultSpan);
TryFormatInvariantG(dateTime, offset, resultSpan, out int charsWritten);
Debug.Assert(charsWritten == FormatInvariantGMaxLength);
return str;
return result;
}
else
{
Expand All @@ -969,7 +971,6 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider
else if (format.Length == 1)
{
int charsWritten;
string str;
switch (format[0])
{
// Round trip format
Expand All @@ -981,24 +982,24 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider

// RFC1123 format
case 'r' or 'R':
str = string.FastAllocateString(FormatRLength);
TryFormatR(dateTime, offset, new Span<char>(ref str.GetRawStringData(), str.Length), out charsWritten);
Debug.Assert(charsWritten == str.Length);
return str;
result = string.Alloc(FormatRLength, out resultSpan);
TryFormatR(dateTime, offset, resultSpan, out charsWritten);
Debug.Assert(charsWritten == result.Length);
return result;

// Sortable format
case 's':
str = string.FastAllocateString(FormatSLength);
TryFormatS(dateTime, new Span<char>(ref str.GetRawStringData(), str.Length), out charsWritten);
Debug.Assert(charsWritten == str.Length);
return str;
result = string.Alloc(FormatSLength, out resultSpan);
TryFormatS(dateTime, resultSpan, out charsWritten);
Debug.Assert(charsWritten == result.Length);
return result;

// Universal time in sortable format
case 'u':
str = string.FastAllocateString(FormatuLength);
TryFormatu(dateTime, offset, new Span<char>(ref str.GetRawStringData(), str.Length), out charsWritten);
Debug.Assert(charsWritten == str.Length);
return str;
result = string.Alloc(FormatuLength, out resultSpan);
TryFormatu(dateTime, offset, resultSpan, out charsWritten);
Debug.Assert(charsWritten == result.Length);
return result;

// Universal time in culture dependent format
case 'U':
Expand All @@ -1021,9 +1022,9 @@ internal static string Format(DateTime dateTime, string? format, IFormatProvider

var vlb = new ValueListBuilder<char>(stackalloc char[256]);
FormatCustomized(dateTime, format, dtfi, offset, ref vlb);
string resultString = vlb.AsSpan().ToString();
result = vlb.AsSpan().ToString();
vlb.Dispose();
return resultString;
return result;
}

internal static bool TryFormat<TChar>(DateTime dateTime, Span<TChar> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) where TChar : unmanaged, IUtfChar<TChar> =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3860,11 +3860,10 @@ private static ReadOnlySpan<byte> GetCultureName(int localeNameIndice)

private static string GetString(ReadOnlySpan<byte> buffer)
{
string result = string.FastAllocateString(buffer.Length);
var s = new Span<char>(ref result.GetRawStringData(), buffer.Length);
string result = string.Alloc(buffer.Length, out Span<char> resultSpan);
for (int i = 0; i < buffer.Length; i++)
{
s[i] = (char)buffer[i];
resultSpan[i] = (char)buffer[i];
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal static string ToLower(string s)
return string.Empty;
}

ReadOnlySpan<char> source = s;
ReadOnlySpan<char> source = s.GetSpan();

int i = 0;
while (i < s.Length)
Expand Down Expand Up @@ -53,11 +53,10 @@ internal static string ToLower(string s)
return s;
}

string result = string.FastAllocateString(s.Length);
var destination = new Span<char>(ref result.GetRawStringData(), result.Length);
ReadOnlySpan<char> src = s;
src.Slice(0, i).CopyTo(destination);
ToLower(src.Slice(i), destination.Slice(i));
string result = string.Alloc(s.Length, out Span<char> resultSpan);
ReadOnlySpan<char> src = s.GetSpan();
src.Slice(0, i).CopyTo(resultSpan);
ToLower(src.Slice(i), resultSpan.Slice(i));

return result;
}
Expand All @@ -69,7 +68,7 @@ internal static string ToUpper(string s)
return string.Empty;
}

ReadOnlySpan<char> source = s;
ReadOnlySpan<char> source = s.GetSpan();

int i = 0;
while (i < s.Length)
Expand Down Expand Up @@ -99,11 +98,10 @@ internal static string ToUpper(string s)
return s;
}

string result = string.FastAllocateString(s.Length);
var destination = new Span<char>(ref result.GetRawStringData(), result.Length);
ReadOnlySpan<char> src = s;
src.Slice(0, i).CopyTo(destination);
ToUpper(src.Slice(i), destination.Slice(i));
string result = string.Alloc(s.Length, out Span<char> resultSpan);
ReadOnlySpan<char> src = s.GetSpan();
src.Slice(0, i).CopyTo(resultSpan);
ToUpper(src.Slice(i), resultSpan.Slice(i));

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,9 @@ private unsafe string ChangeCaseCommon<TConversion>(string source) where TConver
// This will necessarily allocate a new string, but let's try to stay within the managed (non-localization tables)
// conversion code path if we can.

string result = string.FastAllocateString(source.Length); // changing case uses simple folding: doesn't change UTF-16 code unit count
string result = string.Alloc(source.Length, out Span<char> resultSpan); // changing case uses simple folding: doesn't change UTF-16 code unit count

// copy existing known-good data into the result
Span<char> resultSpan = new Span<char>(ref result.GetRawStringData(), result.Length);
source.AsSpan(0, (int)currIdx).CopyTo(resultSpan);

// and re-run the fast span-based logic over the remainder of the data
Expand All @@ -360,12 +359,11 @@ private unsafe string ChangeCaseCommon<TConversion>(string source) where TConver
// We reached non-ASCII data *or* the requested culture doesn't map ASCII data the same way as the invariant culture.
// In either case we need to fall back to the localization tables.

string result = string.FastAllocateString(source.Length); // changing case uses simple folding: doesn't change UTF-16 code unit count
string result = string.Alloc(source.Length, out Span<char> resultSpan); // changing case uses simple folding: doesn't change UTF-16 code unit count

if (currIdx > 0)
{
// copy existing known-good data into the result
Span<char> resultSpan = new Span<char>(ref result.GetRawStringData(), result.Length);
source.AsSpan(0, (int)currIdx).CopyTo(resultSpan);
}

Expand Down
10 changes: 5 additions & 5 deletions src/libraries/System.Private.CoreLib/src/System/Guid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ public static Guid ParseExact(string input, [StringSyntax(StringSyntaxAttribute.
ArgumentNullException.ThrowIfNull(input);
ArgumentNullException.ThrowIfNull(format);

return ParseExact((ReadOnlySpan<char>)input, (ReadOnlySpan<char>)format);
return ParseExact(input.GetSpan(), format.GetSpan());
}

public static Guid ParseExact(ReadOnlySpan<char> input, [StringSyntax(StringSyntaxAttribute.GuidFormat)] ReadOnlySpan<char> format)
Expand Down Expand Up @@ -1176,12 +1176,12 @@ public string ToString([StringSyntax(StringSyntaxAttribute.GuidFormat)] string?
};
}

string guidString = string.FastAllocateString(guidSize);
string result = string.Alloc(guidSize, out Span<char> resultSpan);

bool result = TryFormatCore(new Span<char>(ref guidString.GetRawStringData(), guidString.Length), out int bytesWritten, format);
Debug.Assert(result && bytesWritten == guidString.Length, "Formatting guid should have succeeded.");
bool success = TryFormatCore(resultSpan, out int bytesWritten, format);
Debug.Assert(success && bytesWritten == result.Length, "Formatting guid should have succeeded.");

return guidString;
return result;
}

public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.GuidFormat)] ReadOnlySpan<char> format = default) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,7 @@ public static Span<T> AsSpan<T>(this T[]? array, Range range)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<char> AsSpan(this string? text)
{
if (text == null)
return default;

return new ReadOnlySpan<char>(ref text.GetRawStringData(), text.Length);
return text is not null ? text.GetSpan() : default;
}

/// <summary>
Expand All @@ -122,7 +119,7 @@ public static ReadOnlySpan<char> AsSpan(this string? text, int start)
if ((uint)start > (uint)text.Length)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);

return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), (nint)(uint)start /* force zero-extension */), text.Length - start);
return text.GetSpan().Slice(start);
}

/// <summary>Creates a new <see cref="ReadOnlySpan{Char}"/> over a portion of the target string from a specified position to the end of the string.</summary>
Expand All @@ -148,7 +145,7 @@ public static ReadOnlySpan<char> AsSpan(this string? text, Index startIndex)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex);
}

return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), (nint)(uint)actualIndex /* force zero-extension */), text.Length - actualIndex);
return text.GetSpan().Slice(actualIndex);
}

/// <summary>Creates a new <see cref="ReadOnlySpan{Char}"/> over a portion of a target string using the range start and end indexes.</summary>
Expand All @@ -174,7 +171,7 @@ public static ReadOnlySpan<char> AsSpan(this string? text, Range range)
}

(int start, int length) = range.GetOffsetAndLength(text.Length);
return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), (nint)(uint)start /* force zero-extension */), length);
return text.GetSpan().Slice(start, length);
}

/// <summary>
Expand Down Expand Up @@ -206,7 +203,7 @@ public static ReadOnlySpan<char> AsSpan(this string? text, int start, int length
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
#endif

return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), (nint)(uint)start /* force zero-extension */), length);
return text.GetSpan().Slice(start, length);
}

/// <summary>Creates a new <see cref="ReadOnlyMemory{T}"/> over the portion of the target string.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ public static SearchValues<string> Create(ReadOnlySpan<string> values, bool igno

static string NormalizeIfNeeded(string value, bool ignoreCase)
{
string result = value;

if (ignoreCase && value.AsSpan().ContainsAnyExcept(s_allAsciiExceptLowercase))
{
string upperCase = string.FastAllocateString(value.Length);
int charsWritten = Ordinal.ToUpperOrdinal(value, new Span<char>(ref upperCase.GetRawStringData(), upperCase.Length));
Debug.Assert(charsWritten == upperCase.Length);
value = upperCase;
result = string.Alloc(value.Length, out Span<char> resultSpan);
int charsWritten = Ordinal.ToUpperOrdinal(value, resultSpan);
Debug.Assert(charsWritten == result.Length);
}

return value;
return result;
}

static Span<string> RemoveUnreachableValues(Span<string> values, HashSet<string> unreachableValues)
Expand Down
Loading

1 comment on commit 3401370

@xtqqczze
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.