Last active
October 2, 2020 10:29
-
-
Save sonnemaf/7e6572c8efbbae23714745b1e3c10497 to your computer and use it in GitHub Desktop.
BM for removing bounds check
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
namespace ConsoleApp68 { | |
class Program { | |
static void Main(string[] args) { | |
//var a = new ArrayChunkOfStructs<PointStruct>(new PointStruct[] { | |
// new (1, 2), | |
// new (2, 3), | |
// new (4, 5), | |
// new (6, 7), | |
// new (8, 9), | |
//}); | |
//a[0].Swap(); | |
//a.ItemRef(1).Swap(); | |
//a.ItemRef2(2).Swap(); | |
//a.ItemRef3(3).Swap(); | |
//foreach (var item in a) { | |
// Console.WriteLine(item); | |
//} | |
BenchmarkRunner.Run<BM>(); | |
} | |
} | |
public class BM { | |
private readonly ArrayChunkOfStructs<PointStruct> _array = new(1000); | |
[Benchmark] | |
//public PointStruct Indexer() => _array[2]; | |
public ref PointStruct Indexer() => ref _array[2]; | |
[Benchmark] | |
public ref PointStruct ItemRef() => ref _array.ItemRef(2); | |
[Benchmark] | |
public ref PointStruct ItemRef2() => ref _array.ItemRef2(2); | |
[Benchmark(Baseline = true)] | |
public ref PointStruct ItemRef3() => ref _array.ItemRef3(2); | |
} | |
public class ArrayChunkOfStructs<T> : IEnumerable<T> where T : struct { | |
private readonly T[] _array; | |
public ArrayChunkOfStructs(int size) { | |
_array = new T[size]; | |
} | |
public ArrayChunkOfStructs(T[] array) { | |
_array = array; | |
} | |
//public T this[int index] => _array[index]; | |
public ref T this[int index] => ref _array[index]; | |
public ref T ItemRef(int index) => ref Unsafe.Add(ref _array[0], index); | |
public ref T ItemRef2(int index) { | |
var span = new Span<T>(_array); | |
return ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index); | |
} | |
public ref T ItemRef3(int index) { | |
// Net 5.0 | |
ref var data = ref MemoryMarshal.GetArrayDataReference(_array); | |
return ref Unsafe.Add(ref data, index); | |
} | |
public IEnumerator<T> GetEnumerator() { | |
return ((IEnumerable<T>)_array).GetEnumerator(); | |
} | |
IEnumerator IEnumerable.GetEnumerator() { | |
return _array.GetEnumerator(); | |
} | |
} | |
public struct PointStruct { | |
public int X; | |
public int Y; | |
public PointStruct(int x, int y) { | |
this.X = x; | |
this.Y = y; | |
} | |
public void Swap() { | |
this = new PointStruct(this.Y, this.X); | |
} | |
public double Dist => Math.Sqrt((X * X) + (Y * Y)); | |
public override string ToString() => $"({X.ToString()},{Y.ToString()})"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment