Skip to content

Instantly share code, notes, and snippets.

@JeremyKuhne
Created October 20, 2018 00:34
Show Gist options
  • Save JeremyKuhne/2eb803b80058fa8b108c81352bc31ba0 to your computer and use it in GitHub Desktop.
Save JeremyKuhne/2eb803b80058fa8b108c81352bc31ba0 to your computer and use it in GitHub Desktop.
Perf on slice
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
namespace ConsoleApp10
{
public delegate Span<T> Allocator<T>(int length);
public class SequenceToSpan
{
private ReadOnlySequence<byte> _arraySequence;
private byte[] _array;
private Allocator<byte> _allocator = (length) => new byte[length];
public SequenceToSpan()
{
_array = new byte[10_000];
_arraySequence = new ReadOnlySequence<byte>(_array);
}
[Benchmark]
public ReadOnlySpan<byte> SliceOrCopy_Array()
{
return _arraySequence.SliceOrCopy();
}
[Benchmark]
public ReadOnlySpan<byte> SliceOrCopy_AllocatorArray()
{
return _arraySequence.SliceOrCopy(_allocator);
}
[Benchmark]
public ReadOnlySpan<byte> TwoStage_Array()
{
if (!_arraySequence.TryAsSpan(out ReadOnlySpan<byte> span))
{
Span<byte> scratch = new byte[checked((int)_arraySequence.Length)];
_arraySequence.CopyTo(scratch);
span = scratch;
}
return span;
}
}
public static class SequenceExtensions
{
public static ReadOnlySpan<T> SliceOrCopy<T>(in this ReadOnlySequence<T> sequence)
{
return sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray();
}
public static ReadOnlySpan<T> SliceOrCopy<T>(in this ReadOnlySequence<T> sequence, Allocator<T> allocator)
{
if (sequence.IsSingleSegment)
{
return sequence.First.Span;
}
Span<T> span = allocator(checked((int)sequence.Length));
sequence.CopyTo(span);
return span;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryAsSpan<T>(in this ReadOnlySequence<T> sequence, out ReadOnlySpan<T> span)
{
bool single = sequence.IsSingleSegment;
span = single ? sequence.First.Span : default;
return single;
}
}
public class Program
{
static unsafe void Main(string[] args)
{
Summary summary = BenchmarkRunner.Run<SequenceToSpan>();
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment