using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string longString = "abc123def456ghi789";
ReadOnlySpan<char> span = longString.AsSpan();
var matches = Regex.Matches(longString, @"\d+");
foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}
// 不使用正则表达式,手动处理
int startIndex = 0;
while (startIndex < span.Length)
{
while (startIndex < span.Length &&!char.IsDigit(span[startIndex]))
{
startIndex++;
}
int endIndex = startIndex;
while (endIndex < span.Length && char.IsDigit(span[endIndex]))
{
endIndex++;
}
if (endIndex > startIndex)
{
ReadOnlySpan<char> numberSpan = span.Slice(startIndex, endIndex - startIndex);
Console.WriteLine(new string(numberSpan));
startIndex = endIndex;
}
else
{
startIndex++;
}
}
}
}
性能提升原因
- 减少内存分配:
Span<T>
是一种栈分配的、高效的内存表示方式,它允许在不进行额外堆内存分配的情况下操作数据。传统的字符串操作(如 Substring
等方法)通常会在堆上创建新的字符串对象,这会增加垃圾回收的压力。而 Span<T>
直接在原数据的内存上进行操作,避免了不必要的内存复制和分配,从而提升性能。
- 直接内存访问:
Span<T>
提供了对底层内存的直接访问,这使得代码能够以更高效的方式遍历和处理数据。与通过索引器访问字符串等操作相比,直接内存访问可以减少额外的方法调用开销,提高执行效率。特别是在处理大型字符串时,这种直接访问的优势更加明显。
- 优化的迭代:使用
Span<T>
进行迭代时,可以利用其优化的迭代器实现。这种迭代器能够更有效地遍历数据,避免了一些传统迭代方式中的额外开销,例如装箱和拆箱操作(在处理值类型时)。同时,由于 Span<T>
是栈分配的,迭代过程中的局部性更好,缓存命中率更高,进一步提升了性能。