Skip to content

Instantly share code, notes, and snippets.

@EgorBo
Last active January 9, 2022 21:59
Show Gist options
  • Save EgorBo/baef36b2fb0b31d99464257f9d001e6c to your computer and use it in GitHub Desktop.
Save EgorBo/baef36b2fb0b31d99464257f9d001e6c to your computer and use it in GitHub Desktop.
Benchmarks.cs
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
static class Program
{
static void Main(string[] args)
{
BenchmarkSwitcher.FromAssembly(typeof(MainBenchmarks).Assembly).Run(args);
}
}
public class SimpleBenchmarks
{
string _data = "I am a man who walks alone and when I'm walking a...";
[Benchmark]
public int IndexOf() => _data.IndexOf("walking", StringComparison.Ordinal); // same as _data.AsSpan().IndexOf("walking");
[Benchmark]
public int LastIndexOf() => _data.LastIndexOf("who", StringComparison.Ordinal); // same as _data.AsSpan().LastIndexOf("who");
[Benchmark]
// Unlike IndexOf, Contains is "Ordinal" by default :\
public bool Contains() => _data.Contains("walking");
}
public class MainBenchmarks
{
public IEnumerable<object[]> TestData()
{
// HTTP headers
yield return new object[] { "Connection: keep-aliveRN", "N" };
yield return new object[] { "Connection: keep-aliveRN", "RN" };
yield return new object[] { "Host: 127.0.0.1:5001RN", ": " };
yield return new object[] { "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng," +
"*/*;q=0.8,application/signed-exchange;v=b3;q=0.9RN", "RN" };
yield return new object[] { "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng," +
"*/*;q=0.8,application/signed-exchange;v=b3;q=0.9RN", "Accept" };
yield return new object[] { "Connection: keep-aliveRN", "Accept:" };
yield return new object[] { "Host: 127.0.0.1:5001RN", "5999" };
yield return new object[] { "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng," +
"*/*;q=0.8,application/signed-exchange;v=b3;q=0.9RN", "host" };
// Json
string globalJson = "{RN \"sdk\": {RN \"version\": \"6.0.100\",RN \"allowPrerelease\": true,RN \"rollForward\": \"major\"RN },RN \"tools\": {RN \"dotnet\": \"6.0.100\"RN },RN \"native-tools\": {RN \"cmake\": \"3.16.4\",RN \"python3\": \"3.7.1\"RN }RN }RN ";
yield return new object[] { globalJson, "version" };
yield return new object[] { globalJson, "}RN" };
yield return new object[] { globalJson, "\"cmake\"" };
yield return new object[] { globalJson, "aaaaa" };
// html
yield return new object[] { "<html>Text</html>", "</html>" };
yield return new object[] { "<html>Text</html>", "/" };
yield return new object[] { "<html><body><h1>My First Heading</h1><p>xx</p></body></html>", "</html>" };
yield return new object[] { "<html><body><h1>My First Heading</h1><p>xx</p></body></html>", "</hhhh>" };
//
// first char == last char
yield return new object[] { "ababababababa", "a" };
yield return new object[] { "ababababababa", "aa" };
yield return new object[] { "ababababababa", "ava" };
yield return new object[] { "abababababaabababababababaaababaz", "z" };
yield return new object[] { "abababababaabababababababaaababaz", "a" };
yield return new object[] { "abababababaabababababababaaababa", "aaaaaza" };
yield return new object[] { "abababababaabababababababaaababa", "ava" };
yield return new object[] { "abababababaabababababababaaababa", "aabababa" };
yield return new object[] { "abababababaabababababababaaababa", "aaaaaaaa" };
yield return new object[] { "abababababaabababababababaabababababaabababababaaababa", "aaa" };
yield return new object[] { "abтестababababaabababababababaabababababaabababababaaababa", "тест" };
yield return new object[] { "abababababaabababababababaabababababaabababababababbba", "ava" };
yield return new object[] { "abababababaabababababababaabababababaabababbabababbbaa", "aabababba" };
yield return new object[] { "abababababaabababababababaabababababaabababbabababbbaa", "azaaaaaaaaa" };
yield return new object[] { "ababababaxxxxxbaabababababababaabababababaabababbabababbbaa", "xxxxx" };
yield return new object[] { "abababababaabababababababaabababababaabababbabababbbaxa", "x" };
// worst case for the baseline algorithm
yield return new object[] { "aaaaaaaaaaaaaaaaaaab", "ab" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaab", "aaaaaab" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", "ab" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", "aaaaaaaaaaaaaaab" };
// worst case for the new one
yield return new object[] { "aaaaaaaaaaaaaaaaaa", "bb" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbb" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bb" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bb" };
yield return new object[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbb" };
}
[Benchmark]
[ArgumentsSource(nameof(TestData))]
public int IndexOf(string source, string str) => source.AsSpan().IndexOf(str);
[Benchmark]
[ArgumentsSource(nameof(TestData))]
public int LastIndexOf(string source, string str) => source.AsSpan().LastIndexOf(str);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment