Skip to content

Instantly share code, notes, and snippets.

@leandromoh
Last active March 9, 2022 22:11
Show Gist options
  • Save leandromoh/51a13faa18dccdc87c4740f554e5e5de to your computer and use it in GitHub Desktop.
Save leandromoh/51a13faa18dccdc87c4740f554e5e5de to your computer and use it in GitHub Desktop.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using System.Buffers;
using System.Text;
public class Program
{
public static async Task Main(string[] args)
{
#if DEBUG
await new VariableLengthReaderBenchmark().Generate();
#else
var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
#endif
}
}
// ``` ini
//
// BenchmarkDotNet=v0.13.1, OS=Windows 10.0.18363.1440 (1909/November2019Update/19H2)
// Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
// .NET SDK=6.0.100
// [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
// .NET 6.0 : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
//
// Job=.NET 6.0 Runtime=.NET 6.0
//
// ```
// | Method | Count | KeySize | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
// |---------------- |--------- |-------- |-----------:|---------:|---------:|----------:|----------:|----------:|-----------:|
// | Generate | 1000000 | 7 | 241.3 ms | 3.75 ms | 3.68 ms | - | - | - | 250 KB |
// | Generate_unique | 1000000 | 7 | 408.0 ms | 8.00 ms | 12.22 ms | 1000.0000 | 1000.0000 | 1000.0000 | 18,426 KB |
// | Generate | 10000000 | 7 | 2,450.7 ms | 27.99 ms | 26.18 ms | - | - | - | 1,004 KB |
// | Generate_unique | 10000000 | 7 | 4,609.6 ms | 42.15 ms | 39.43 ms | 1000.0000 | 1000.0000 | 1000.0000 | 157,255 KB |
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net60)]
public class VariableLengthReaderBenchmark
{
[Params(1_000_000, 10_000_000)]
public int Count { get; set; }
[Params(7)]
public int KeySize { get; set; }
[Benchmark]
public async Task Generate()
{
var fullFileName = GetFileName();
await using var streamWriter = new StreamWriter(path: fullFileName, append: false, Encoding.UTF8, bufferSize: (int)Math.Pow(2, 15));
var i = 0;
foreach (var key in GenerateKeys(KeySize))
{
if (i++ == Count)
break;
await streamWriter.WriteLineAsync(key);
}
}
[Benchmark]
public async Task Generate_unique()
{
var fullFileName = GetFileName();
await using var streamWriter = new StreamWriter(path: fullFileName, append: false, Encoding.UTF8, bufferSize: (int)Math.Pow(2, 15));
var i = 0;
var uniques = new HashSet<int>(Count);
foreach (var key in GenerateKeys(KeySize))
{
if (uniques.Add(string.GetHashCode(key.Span)) is false)
continue;
if (i++ == Count)
break;
await streamWriter.WriteLineAsync(key);
}
}
string GetFileName() => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "keys.txt");
IEnumerable<ReadOnlyMemory<char>> GenerateKeys(int keySize)
{
const int min = 'A';
const int max = 'Z';
var buffer = ArrayPool<char>.Shared.Rent(keySize);
var memory = buffer.AsMemory().Slice(0, keySize);
var random = new Random();
var hashSet = new HashSet<char>(keySize);
try
{
for (int line = 0, written = 0; ; line++, written = 0)
{
while (written < keySize)
{
var c = (char)random.Next(min, max);
if (hashSet.Add(c))
{
buffer[written++] = c;
}
}
yield return memory;
hashSet.Clear();
}
}
finally
{
ArrayPool<char>.Shared.Return(buffer);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment