Skip to content

skepee-LAB/CSharp-Optimization

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Benchmark Optimization

Introduction

C# Optimizations tips and tricks.

1. ReadOnlySpan() instead of Substring()

Instead of using .Substring() it is suggested of using .AsSpan() Click here for a detailed description and here and then hereand here.

Span<T> is a ref struct that is allocated on the stack rather than on the managed heap. 
Ref struct types have a number of restrictions to ensure that they cannot be promoted to the managed heap, 
including that they can't be boxed, they can't be assigned to variables of type Object, dynamic or to any interface type, 
they can't be fields in a reference type, and they can't be used across await and yield boundaries. In addition, calls to two methods, 
Equals(Object) and GetHashCode, throw a NotSupportedException.

Remarks:

No memory allocation. Looking at this code:

string s = "Hello world. This is a test!";
var a = s.AsSpan(0, 4);
var b = s.AsSpan(22);

In Visual Studio it is possible to show Memory allocation during Debug here:

By writing s it is possible to show the memory allocated for the string: SubstringMemAllocation1

Insted by writing a or b we can see: SubstringMemAllocation2

SubstringMemAllocation3

Benchmarks

We have used BenchmarkDotNet to test the performance of using AsSpan() comparing different ways of using a substring and a concat.

  [Benchmark]
  public void TestSubstring()
  {
      var res= string.Concat(test.Substring(0, 5), test.Substring(22));
  }

  [Benchmark]
  public void TestSpan()
  {
      var res = string.Concat(test.AsSpan(0, 4), test.AsSpan(22));
  }

  [Benchmark]
  public void TestSpanToString()
  {
      var res = test.AsSpan(0, 5).ToString() + test.AsSpan(22).ToString();
  }

  [Benchmark]
  public void TestSpanToStringConcat()
  {
      var res = string.Concat(test.AsSpan(0, 5).ToString(), test.AsSpan(22).ToString());
  }

As we can see the use of ReadOnlySpan has less memory allocation and then best performance.

Method Mean Error StdDev Gen0 Allocated
TestSpan 9.881 ns 0.1063 ns 0.1591 ns 0.0076 48 B
TestSubstring 26.882 ns 0.3570 ns 0.5343 ns 0.0191 120 B
TestSpanToString 27.900 ns 0.4150 ns 0.6083 ns 0.0191 120 B
TestSpanToStringConcat 28.036 ns 0.3850 ns 0.5762 ns 0.0191 120 B

Releases

No releases published

Packages