Skip to content

Instantly share code, notes, and snippets.

@mgravell
Created January 25, 2024 14:09
Show Gist options
  • Save mgravell/3442da14e5cb5b873dd5e8d51fc26594 to your computer and use it in GitHub Desktop.
Save mgravell/3442da14e5cb5b873dd5e8d51fc26594 to your computer and use it in GitHub Desktop.
float parsing
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Buffers;
using System.Text.Json;
// prove impl
var obj = new MyBench { Count = 5 };
obj.Init();
Console.WriteLine(obj.Payload);
Console.WriteLine(string.Join(',', obj.Linq()));
Console.WriteLine(string.Join(',', obj.Json()));
Console.WriteLine(string.Join(',', obj.Manual()));
// bench
BenchmarkRunner.Run(typeof(MyBench).Assembly);
[MemoryDiagnoser]
public class MyBench
{
[Params(1, 3, 20, 200)]
public int Count { get; set; }
[GlobalSetup]
public void Init()
{
Random rand = new Random(1234151);
Payload = "[" + string.Join(',', Enumerable.Range(0, Count).Select(x => rand.Next(0,1000) / rand.Next(0,3) switch
{
0 => 1f,
1 => 10f,
_ => 100f
})) + "]";
}
public string Payload { get; private set; } = "[10,20.5,30.88]";
[Benchmark]
public float[] Linq() => Payload.Substring(1, Payload.Length-2).Split(',').Select(s => float.Parse(s)).ToArray();
[Benchmark]
public float[] Json() => JsonSerializer.Deserialize<float[]>(Payload)!;
[Benchmark]
public float[] Manual()
{
SequenceReader<char> r = new(new(Payload.AsMemory().Slice(1, Payload.Length - 2)));
var copy = r;
int count = 1; // count first
while (r.TryAdvanceTo(',')) count++;
// now repeat
float[] arr = new float[count];
r = copy;
int i = 0;
while (r.TryReadTo(out ReadOnlySpan<char> tok, ','))
{
arr[i++] = float.Parse(tok);
}
arr[i++] = float.Parse(r.UnreadSpan);
return arr;
}
}
| Method | Count | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|------- |------ |------------:|----------:|----------:|-------:|-------:|----------:|
| Linq | 1 | 54.32 ns | 0.293 ns | 0.245 ns | 0.0086 | - | 144 B |
| Json | 1 | 113.54 ns | 0.336 ns | 0.298 ns | 0.0062 | - | 104 B |
| Manual | 1 | 72.60 ns | 0.232 ns | 0.217 ns | 0.0019 | - | 32 B |
| Linq | 3 | 131.29 ns | 0.726 ns | 0.679 ns | 0.0167 | - | 280 B |
| Json | 3 | 182.91 ns | 1.264 ns | 1.182 ns | 0.0067 | - | 112 B |
| Manual | 3 | 137.58 ns | 0.305 ns | 0.270 ns | 0.0024 | - | 40 B |
| Linq | 20 | 676.51 ns | 2.932 ns | 2.449 ns | 0.0706 | - | 1184 B |
| Json | 20 | 784.94 ns | 5.818 ns | 5.443 ns | 0.0277 | - | 472 B |
| Manual | 20 | 913.55 ns | 4.204 ns | 3.932 ns | 0.0057 | - | 104 B |
| Linq | 200 | 6,868.95 ns | 81.107 ns | 75.868 ns | 0.6332 | 0.0076 | 10664 B |
| Json | 200 | 6,634.72 ns | 43.096 ns | 40.312 ns | 0.1755 | - | 3056 B |
| Manual | 200 | 8,923.92 ns | 21.489 ns | 17.944 ns | 0.0458 | - | 824 B |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment