Skip to content

Instantly share code, notes, and snippets.

@Henr1k80
Created March 3, 2023 10:12
Show Gist options
  • Save Henr1k80/10e28299fa383439d6c29ee281d76e1b to your computer and use it in GitHub Desktop.
Save Henr1k80/10e28299fa383439d6c29ee281d76e1b to your computer and use it in GitHub Desktop.
Benchmark of CollectionsMarshal.AsSpan with PGO
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
Summary? summary = BenchmarkRunner.Run<AsSpanBenchmark>();
[MemoryDiagnoser]
[Config(typeof(MyEnvVars))]
public class AsSpanBenchmark
{
// Custom config to define "Default vs PGO"
class MyEnvVars : ManualConfig
{
public MyEnvVars()
{
// Use .NET 6.0 default mode:
AddJob(Job.Default.WithId("Default mode"));
// Use Dynamic PGO mode:
AddJob(Job.Default.WithId("Dynamic PGO")
.WithEnvironmentVariables(
new EnvironmentVariable("DOTNET_TieredPGO", "1"),
new EnvironmentVariable("DOTNET_TC_QuickJitForLoops", "1"),
new EnvironmentVariable("DOTNET_ReadyToRun", "0")));
}
}
private const int NumberToWorkOnSoItIsNotOptimizedAwaySeed = 1337;
private static readonly Random Random = new(60);
[Params(0, 1, 2, 3, 4)]
public ushort ListSize { get; set; }
private List<int> _list = new();
[GlobalSetup]
public void GlobalSetup()
{
_list = new List<int>(ListSize);
for (var i = 0; i < ListSize; i++)
_list.Add(Random.Next(int.MinValue, int.MaxValue));
}
[Benchmark]
public int ForEach()
{
int numberToWorkOnSoItIsNotOptimizedAway = NumberToWorkOnSoItIsNotOptimizedAwaySeed;
foreach (int number in _list)
numberToWorkOnSoItIsNotOptimizedAway ^= number;
return numberToWorkOnSoItIsNotOptimizedAway;
}
[Benchmark]
public int For()
{
int numberToWorkOnSoItIsNotOptimizedAway = NumberToWorkOnSoItIsNotOptimizedAwaySeed;
for (var index = 0; index < _list.Count; index++)
numberToWorkOnSoItIsNotOptimizedAway ^= _list[index];
return numberToWorkOnSoItIsNotOptimizedAway;
}
[Benchmark]
public int AsSpanForeach()
{
int numberToWorkOnSoItIsNotOptimizedAway = NumberToWorkOnSoItIsNotOptimizedAwaySeed;
foreach (int number in CollectionsMarshal.AsSpan(_list))
numberToWorkOnSoItIsNotOptimizedAway ^= number;
return numberToWorkOnSoItIsNotOptimizedAway;
}
[Benchmark]
public int AsSpanFor()
{
int numberToWorkOnSoItIsNotOptimizedAway = NumberToWorkOnSoItIsNotOptimizedAwaySeed;
Span<int> span = CollectionsMarshal.AsSpan(_list);
for (var index = 0; index < span.Length; index++)
numberToWorkOnSoItIsNotOptimizedAway ^= span[index];
return numberToWorkOnSoItIsNotOptimizedAway;
}
[Benchmark]
public int RiderSuggestedLinq()
{
return _list.Aggregate(NumberToWorkOnSoItIsNotOptimizedAwaySeed, (current, t) => current ^ t);
}
}
@Henr1k80
Copy link
Author

Henr1k80 commented Mar 3, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment