Skip to content

Instantly share code, notes, and snippets.

@jigargandhi
Last active November 2, 2019 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jigargandhi/ecebb30ed10fa8d7eb40506c73aa78da to your computer and use it in GitHub Desktop.
Save jigargandhi/ecebb30ed10fa8d7eb40506c73aa78da to your computer and use it in GitHub Desktop.
StringExtensions for Memory<T> type
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.0.100
  [Host]     : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT

Method Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
StandardWordCounter 42.14 us 0.2934 us 0.2601 us 14.2822 2.8076 - 67376 B
StringSplitReturnIEnumerable 44.51 us 0.3816 us 0.3383 us - - - 88 B
StringSplitPassDelegate 28.36 us 0.2781 us 0.2602 us - - - -
Raw 16.34 us 0.3226 us 0.3716 us - - - -
using BenchmarkDotNet.Attributes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
[MemoryDiagnoser]
public class SplitWordBenchmarks
{
[GlobalSetup]
public void Initialize()
{
sentence = File.ReadAllText(@"input.txt");
}
public string sentence { get; set; }
[Benchmark]
public void StandardWordCounter()
{
string[] words = sentence.Split(' ');
foreach (var word in words)
{
}
}
[Benchmark]
public void StringSplitReturnIEnumerable()
{
var readonlyData = sentence.SplitEx(' ');
foreach (var item in readonlyData)
{
}
}
[Benchmark]
public void StringSplitPassDelegate()
{
sentence.SplitExByAction<object>(' ', null, (state, span) =>
{
});
}
[Benchmark]
public void Raw()
{
char split = ' ';
ReadOnlySpan<char> span = sentence.AsSpan();
int oldIndex = 0;
for (int i = 0; i < span.Length; i++)
{
if (split == span[i])
{
var slicedSpan = span.Slice(oldIndex, i - oldIndex + 1);
oldIndex = i + 1;
// Do something with the slicedSpan
}
}
}
}
public static class StringExtensions
{
public static IEnumerable<ReadOnlyMemory<char>> SplitEx(this string input, char split)
{
ReadOnlyMemory<char> span = input.AsMemory();
int oldIndex = 0;
for (int i = 0; i < span.Length; i++)
{
if (split == span.Span[i])
{
var slicedMemory = span.Slice(oldIndex, i - oldIndex + 1);
oldIndex = i + 1;
yield return slicedMemory;
}
}
}
public static void SplitExByAction<T>(this string input, char split, T state, Action<T, ReadOnlyMemory<char>> action)
{
ReadOnlyMemory<char> span = input.AsMemory();
int oldIndex = 0;
for (int i = 0; i < span.Length; i++)
{
if (split == span.Span[i])
{
var slicedMemory = span.Slice(oldIndex, i - oldIndex + 1);
oldIndex = i + 1;
action(state, slicedMemory);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment