Skip to content

Instantly share code, notes, and snippets.

@sonnemaf
Last active October 2, 2020 10:29
Embed
What would you like to do?
BM for removing bounds check
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