Skip to content

Instantly share code, notes, and snippets.

@AlexRadch
Forked from teoadal/ArrayReadBenchmark.cs
Last active March 15, 2023 13:51
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 AlexRadch/debdd940408204ac0f817ae50b5b5eea to your computer and use it in GitHub Desktop.
Save AlexRadch/debdd940408204ac0f817ae50b5b5eea to your computer and use it in GitHub Desktop.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace Storage.Benchmark;
[SimpleJob(RuntimeMoniker.Net80)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[SimpleJob(RuntimeMoniker.Net48)]
[MeanColumn]
public class ArrayReadBenchmark {
[Benchmark]
public int For() {
var sum = 0;
for (var i = 0; i < _array.Length; i++) {
sum += _array[i];
}
return sum;
}
[Benchmark(Baseline = true)]
public int Foreach() {
var sum = 0;
foreach (var element in _array) {
sum += element;
}
return sum;
}
//[Benchmark]
//public int ForeachCustom() {
// var sum = 0;
// foreach (var element in new ArrayEnumerator<int>(_array)) {
// sum += element;
// }
// return sum;
//}
[Benchmark]
public int ForeachSpan() {
var sum = 0;
foreach (var element in _array.AsSpan()) {
sum += element;
}
return sum;
}
[Benchmark]
public int ForUnsafeRef() {
var sum = 0;
ref int refStart = ref MemoryMarshal.GetReference<int>(_array);
for (var i = 0; i < _array.Length; i++) {
sum += Unsafe.Add(ref refStart, i);
}
return sum;
}
[Benchmark]
public int ForUnsafe2Refs() {
var sum = 0;
for (ref int refItem = ref MemoryMarshal.GetReference<int>(_array),
refEnd = ref Unsafe.Add(ref refItem, _array.Length);
Unsafe.IsAddressLessThan(ref refItem, ref refEnd);
refItem = ref Unsafe.Add(ref refItem, 1))
{
sum += refItem;
}
return sum;
}
[Benchmark]
public unsafe int ForUnsafePointer() {
var sum = 0;
fixed (int* arrayPtr = &_array[0]) {
for (var index = 0; index < _array.Length; index++) {
sum += *(arrayPtr + index);
}
}
return sum;
}
[Benchmark]
public unsafe int ForUnsafe2Pointers() {
var sum = 0;
fixed (int* arrayPtr = _array) {
for (int* ptr = arrayPtr,
endPtr = arrayPtr + _array.Length;
ptr < endPtr;
ptr++)
{
sum += *ptr;
}
}
return sum;
}
#region Configuration
private int[] _array = null!;
[GlobalSetup]
public void Init() {
const int count = 1021;
_array = new int[count];
var rnd = new Random(1234);
for (var i = 0; i < count; i++) {
_array[i] = rnd.Next(0, 10);
}
}
#endregion
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net7.0;net6.0;netcoreapp3.1;net48;</TargetFrameworks>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
</ItemGroup>
</Project>
using BenchmarkDotNet.Running;
using Storage.Benchmark;
var _ = BenchmarkRunner.Run<ArrayReadBenchmark>(null!, args);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment