title: C# .NET Core 2.1 Span<T> and Memory<T> Performance Considerations
body: <pre><code>using System.Buffers;
  
  const byte carriageReturn = (byte)'\r';
  const int arbitrarySliceStart = 5;
  
  // using Memory&lt;T&gt;
  async Task&lt;int&gt; ReadAsyncWithMemory(Stream sourceStream, int bufferSize)
  {
      var buffer = ArrayPool&lt;byte&gt;.Shared.Rent(bufferSize);
      var bytesRead = await sourceStream.ReadAsync(buffer);
      var memory = buffer.AsMemory(arbitrarySliceStart, bytesRead);
      var endOfNumberIndex = memory.Span.IndexOf(carriageReturn);
      var memoryChunk = memory.Slice(0, endOfNumberIndex);
      var number = BitConverter.ToInt32(memoryChunk.Span);
      ArrayPool&lt;byte&gt;.Shared.Return(buffer);
      return number;
  }
  
  // using Span&lt;T&gt; without assigning to variable
  async Task&lt;int&gt; ReadAsyncWithSpan(Stream sourceStream, int bufferSize)
  {
      var buffer = ArrayPool&lt;byte&gt;.Shared.Rent(bufferSize);
      var bytesRead = await sourceStream.ReadAsync(buffer);
      var endOfNumberIndex = buffer.AsSpan(arbitrarySliceStart, bytesRead).IndexOf(carriageReturn);
      var number = BitConverter.ToInt32(buffer.AsSpan(arbitrarySliceStart, bytesRead).Slice(0, endOfNumberIndex));
      ArrayPool&lt;byte&gt;.Shared.Return(buffer);
      return number;
  }
  
  // using Span&lt;T&gt; with additional local or private function
  async Task&lt;int&gt; ReadAsyncWithSpanAndAdditionalFunction(Stream sourceStream, int bufferSize)
  {
      var buffer = ArrayPool&lt;byte&gt;.Shared.Rent(bufferSize);
      var bytesRead = await sourceStream.ReadAsync(buffer);
  
      var number = SliceNumer();
      ArrayPool&lt;byte&gt;.Shared.Return(buffer);
      return number;
  
      int SliceNumer()
      {
          var span = buffer.AsSpan(arbitrarySliceStart, bytesRead);
          var endOfNumberIndex = span.IndexOf(carriageReturn);
          var numberSlice = span.Slice(0, endOfNumberIndex);
          return BitConverter.ToInt32(numberSlice);
      }
  }
  </code></pre>
  
  <p>I read the <a href="https://msdn.microsoft.com/en-us/magazine/mt814808.aspx" rel="noreferrer">MSDN</a> and <a href="https://www.codemag.com/Article/1807051/Introducing-.NET-Core-2.1-Flagship-Types-Span-T-and-Memory-T" rel="noreferrer">CodeMag</a> articles about <code>Span&lt;T&gt;</code>, but I still had a question about their performance.</p>
  
  <p>I understand that <code>Span&lt;T&gt;</code> is more performant than <code>Memory&lt;T&gt;</code>, but I guess I'd like to know to what degree.  I have 3 example methods posted and I'd like to know which is the best approach.</p>
  
  <p><strong>1. <code>Memory&lt;T&gt;</code> only</strong></p>
  
  <p>The first function, <code>ReadAsyncWithMemory</code>, only uses <code>Memory&lt;T&gt;</code> to handle the work, pretty straightforward.</p>
  
  <p><strong>2. <code>Span&lt;T&gt;</code> with no local variables</strong></p>
  
  <p>In the second function, <code>ReadAsyncWithSpan</code>, <code>Span&lt;T&gt;</code> is used instead, but no local variables are created, and the call <code>buffer.AsSpan(arbitrarySliceStart, bytesRead)</code> is made twice, which seems clunky.  However, if <code>Span&lt;T&gt;</code> is more performant than <code>Memory&lt;T&gt;</code>, is it worth the double call?</p>
  
  <p><strong>2. <code>Span&lt;T&gt;</code> with additional function</strong></p>
  
  <p>In the third function, <code>ReadAsyncWithSpanAndAdditionalFunction</code>, a local function is introduced so that <code>Span&lt;T&gt;</code> can be used for memory operations.  Now the question is, is calling a new function and introducing a new stack frame worth the performance gains of using <code>Span&lt;T&gt;</code> over <code>Memory&lt;T&gt;</code>?</p>
  
  <p><strong>Final Questions</strong></p>
  
  <ul>
  <li>Does adding a local variable for a span cause additional overhead?
  
  <ul>
  <li>Is it worth losing readability to just inline the <code>Span&lt;T&gt;</code> without assigning it to a variable?</li>
  </ul></li>
  <li>Is calling an additional function in order to use <code>Span&lt;T&gt;</code> over <code>Memory&lt;T&gt;</code> worth the overhead of the new function and stack frame?</li>
  <li>Is <code>Memory&lt;T&gt;</code> significantly less performant than <code>Span&lt;T&gt;</code> when it is constrained to just a stack frame and not allocated to the heap?</li>
  </ul>