1
Performance comparison, AsSpan() vs Substring()
Date Added (UTC):
08 May 2024 @ 15:17
Date Updated (UTC):08 May 2024 @ 15:17
.NET Version(s): Tag(s):
Added By:
.NET developer|Systems engineer|Databases(SQL)
Benchmark Results:
Benchmark Code:
Originally imported from :
https://gist.github.com/PhilsKay/0d3f56bca16e31186ce835704b6b7f03on 08 May 2024 @ 15:17 (UTC) .
The original benchmark may have changed.
https://gist.github.com/PhilsKay/0d3f56bca16e31186ce835704b6b7f03
The original benchmark may have changed.
[SimpleJob(RuntimeMoniker.Net80)]
[MemoryDiagnoser]
public class PerformanceCheck
{
[Benchmark]
public ReadOnlySpan<char> AsSpan()
{
string text = "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32.";
return text.AsSpan(15, 150);
}
[Benchmark(Baseline = true)]
public string SubString()
{
string text = "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32.";
return text.Substring(15, 150);
}
}
Powered by SharpLab
// .NET 8
public ReadOnlySpan<char> AsSpan()
{
return MemoryExtensions.AsSpan("Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32.", 15, 150);
}
// .NET 8
public string SubString()
{
return "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32.".Substring(15, 150);
}
Powered by SharpLab
// .NET 8
.method public hidebysig
instance valuetype [System.Runtime]System.ReadOnlySpan`1<char> AsSpan () cil managed
{
.custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
01 00 10 00 00 00 01 5f 00 00
)
// Method begins at RVA 0x2050
// Code size 18 (0x12)
.maxstack 8
// sequence point: (line 19, col 10) to (line 19, col 794) in _
IL_0000: ldstr "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32."
// sequence point: (line 21, col 10) to (line 21, col 38) in _
IL_0005: ldc.i4.s 15
IL_0007: ldc.i4 150
IL_000c: call valuetype [System.Runtime]System.ReadOnlySpan`1<char> [System.Memory]System.MemoryExtensions::AsSpan(string, int32, int32)
IL_0011: ret
}
// .NET 8
.method public hidebysig
instance string SubString () cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (
01 00 01 00 00
)
.custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
01 00 18 00 00 00 01 5f 01 00 54 02 08 42 61 73
65 6c 69 6e 65 01
)
// Method begins at RVA 0x2063
// Code size 18 (0x12)
.maxstack 8
// sequence point: (line 27, col 10) to (line 27, col 794) in _
IL_0000: ldstr "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32."
// sequence point: (line 29, col 10) to (line 29, col 41) in _
IL_0005: ldc.i4.s 15
IL_0007: ldc.i4 150
IL_000c: callvirt instance string [System.Runtime]System.String::Substring(int32, int32)
IL_0011: ret
}
Powered by SharpLab
|
|
Benchmark Description:
AsSpan() is much faster than Substring.
AsSpan requires no or less memory allocation than Substring.
The benchmark setup provided is designed to measure and compare the performance of two different methods for extracting a substring from a larger string in C#. The benchmarks are configured to run on the .NET 8.0 runtime, as indicated by the `[SimpleJob(RuntimeMoniker.Net80)]` attribute. This ensures that the benchmarks are executed using the latest optimizations and runtime features available in .NET 8.0. The `[MemoryDiagnoser]` attribute is used to enable the collection and reporting of memory allocation statistics, which is crucial for understanding the memory efficiency of the compared methods.
### Benchmark Methods Overview
#### 1. `AsSpan()` Method
**Rationale and Performance Aspect:**
The `AsSpan()` method is designed to test the performance of creating a `ReadOnlySpan<char>` from a substring of a larger string without actually allocating a new string for the substring. This method uses the `AsSpan` extension method on a string, which provides a type-safe, memory-efficient view of the characters in the string. The rationale behind testing this method is to evaluate how efficiently one can perform substring operations without the overhead of additional memory allocations associated with creating a new string.
**What It Measures:**
This benchmark measures the time it takes to create a `ReadOnlySpan<char>` representing a portion of the original string and the memory efficiency of this operation. It's important because it reflects the performance characteristics of substring operations in scenarios where memory allocation overhead is critical, such as in high-performance or memory-constrained environments.
**Expected Results/Insights:**
Running this benchmark should provide insights into how much faster and memory-efficient `ReadOnlySpan<char>` is compared to traditional substring methods that involve allocations. Lower memory usage and faster execution times are expected outcomes due to the avoidance of heap allocations.
#### 2. `SubString()` Method (Baseline)
**Rationale and Performance Aspect:**
The `SubString()` method serves as the baseline for comparison and is designed to test the traditional approach of extracting a substring, which involves creating a new string object that contains a portion of the original string. This method uses the `Substring` method of the string class, which allocates memory for the new string. The rationale behind including this method is to have a baseline that represents the common but more memory-intensive way of handling substrings.
**What It Measures:**
This benchmark measures the time and memory allocations involved in extracting a substring using the `Substring` method. It's an important measure because it reflects the cost of substring operations in terms of both execution time and memory usage in a typical .NET application.
**Expected Results/Insights:**
From running this benchmark, one should expect to see how much additional memory is allocated and possibly a slower execution time compared to the `AsSpan` method. This method serves as a reference point to understand the benefits of using `ReadOnlySpan<char>` for substring operations in terms of performance and memory efficiency.
### Conclusion
By comparing the results of these two benchmarks, developers can make informed decisions about which method to use for substring operations based on their specific performance and memory allocation requirements. The `AsSpan` method is anticipated to be more efficient, especially in scenarios where minimizing memory usage is crucial, while the `SubString` method provides a straightforward but potentially more costly approach in terms of memory.