CA1846: Prefer AsSpan
over Substring
Property | Value |
---|---|
Rule ID | CA1846 |
Title | Prefer AsSpan over Substring |
Category | Performance |
Fix is breaking or non-breaking | Non-breaking |
Enabled by default in .NET 8 | As suggestion |
Cause
The result of a call to one of the String.Substring overloads is passed to a method with an available overload that accepts ReadOnlySpan<Char>
.
Rule description
Substring
allocates a new string
object on the heap and performs a full copy of the extracted text. String manipulation is a performance bottleneck for many programs. Allocating many small, short-lived strings on a hot path can create enough collection pressure to impact performance. The O(n) copies created by Substring
become relevant when the substrings get large. The Span<T> and ReadOnlySpan<T> types were created to solve these performance problems.
Many APIs that accept strings also have overloads that accept a ReadOnlySpan<System.Char>
argument. When such overloads are available, you can improve performance by calling AsSpan
instead of Substring
.
How to fix violations
To fix a violation of this rule, replace the call to string.Substring
with a call to one of the MemoryExtensions.AsSpan extension methods.
using System;
public void MyMethod(string iniFileLine)
{
// Violation
int.TryParse(iniFileLine.Substring(7), out int x);
int.TryParse(iniFileLine.Substring(2, 5), out int y);
// Fix
int.TryParse(iniFileLine.AsSpan(7), out int x);
int.TryParse(iniFileLine.AsSpan(2, 5), out int y);
}
Imports System
Public Sub MyMethod(iniFileLine As String)
Dim x As Integer
Dim y As Integer
' Violation
Integer.TryParse(iniFileLine.Substring(7), x)
Integer.TryParse(iniFileLine.Substring(2, 5), y)
' Fix
Integer.TryParse(iniFileLine.AsSpan(7), x)
Integer.TryParse(iniFileLine.AsSpan(2, 5), y)
End Sub
When to suppress warnings
It is safe to suppress warnings from this rule if performance is not a concern.