Skip to content

Instantly share code, notes, and snippets.

@badamczewski
Last active August 21, 2020 18:48
Show Gist options
  • Save badamczewski/e0cd62c25b20311104a666cde4c61a53 to your computer and use it in GitHub Desktop.
Save badamczewski/e0cd62c25b20311104a666cde4c61a53 to your computer and use it in GitHub Desktop.
| Method | Mean | Error | StdDev | Ratio | RatioSD |
|------------------------------------- |----------:|----------:|----------:|------:|--------:|
| SkipLinq | 47.386 ns | 0.4797 ns | 0.4487 ns | 1.00 | 0.00 |
| SkipHyperLinq | 31.090 ns | 0.3779 ns | 0.3350 ns | 0.66 | 0.01 |
| SkipLinq_Custom_List | 73.336 ns | 1.3644 ns | 1.2095 ns | 1.55 | 0.03 |
| SkipLinq_Custom_List_2 | 71.604 ns | 1.3169 ns | 1.4090 ns | 1.51 | 0.03 |
| SkipLinq_Custom_Enumerable | 48.463 ns | 0.7997 ns | 0.7089 ns | 1.02 | 0.02 |
| SkipLinq_Custom_Enumerable_AsClass | 40.907 ns | 0.3217 ns | 0.2687 ns | 0.86 | 0.01 |
| SkipLinq_Custom_Enumerable_DF_NoVirt | 2.329 ns | 0.0407 ns | 0.0340 ns | 0.05 | 0.00 |
CODE:
public class Benchmark
{
private List<int> list;
[GlobalSetup]
public void Global()
{
list = Enumerable.Range(0, 15).ToList();
}
[Benchmark(Baseline = true)]
public int SkipLinq()
{
return LinqPerf_6.SkipLinq(list, 9);
}
[Benchmark]
public int SkipHyperLinq()
{
return list.Skip(9).FirstOrDefault();
}
[Benchmark]
public int SkipLinq_Custom_List()
{
return LinqPerf_6.SkipLinq_Custom_List(list, 9);
}
[Benchmark]
public int SkipLinq_Custom_List_2()
{
return LinqPerf_6.SkipLinq_Custom_List_2(list, 9);
}
[Benchmark]
public int SkipLinq_Custom_Enumerable()
{
return LinqPerf_6.SkipLinq_Custom_Enumerable(list, 9);
}
[Benchmark]
public int SkipLinq_Custom_Enumerable_AsClass()
{
return LinqPerf_6.SkipLinq_Custom_Enumerable_AsClass(list, 9);
}
[Benchmark]
public int SkipLinq_Custom_Enumerable_DF_NoVirt()
{
return LinqPerf_6.SkipLinq_Custom_Enumerable_DF_NoVirt(list, 9);
}
}
public readonly struct SkipEnumerable<TSource> : IEnumerable<TSource>
{
public readonly int skip;
public readonly List<TSource> source;
public SkipEnumerable(List<TSource> source, int skip)
{
this.skip = skip;
this.source = source;
}
public SkipEnumerable(SkipEnumerable<TSource> source, int skip)
{
this.skip = source.skip + skip;
this.source = source.source;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator()
{
return new Enumerator(in this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(in this);
}
IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
{
return new Enumerator(in this);
}
public struct Enumerator : IEnumerator<TSource>
{
readonly List<TSource> source;
public int index;
public Enumerator(in SkipEnumerable<TSource> skip)
{
index = -1;
this.source = skip.source;
this.index += skip.skip;
}
public TSource Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => source[index];
}
object IEnumerator.Current => throw new NotImplementedException();
public void Dispose()
{
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
if (++index < source.Count)
{
return true;
}
return false;
}
public void Reset()
{
}
}
}
public class SkipEnumerableClass<TSource> : IEnumerable<TSource>
{
public readonly int skip;
public readonly List<TSource> source;
public SkipEnumerableClass(List<TSource> source, int skip)
{
this.skip = skip;
this.source = source;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
{
return new Enumerator(this);
}
public class Enumerator : IEnumerator<TSource>
{
readonly List<TSource> source;
public int index;
public Enumerator(in SkipEnumerableClass<TSource> skip)
{
index = -1;
this.source = skip.source;
this.index += skip.skip;
}
public TSource Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => source[index];
}
object IEnumerator.Current => throw new NotImplementedException();
public void Dispose()
{
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
if (++index < source.Count)
{
return true;
}
return false;
}
public void Reset()
{
}
}
}
public static class SuperLinq
{
public static IEnumerable<TSource> SkipLinq_Custom_Enumerable<TSource>(this List<TSource> source, int count)
{
return new SkipEnumerable<TSource>(source, count);
}
public static IEnumerable<TSource> SkipLinq_Custom_Enumerable_AsClass<TSource>(this List<TSource> source, int count)
{
return new SkipEnumerableClass<TSource>(source, count);
}
public static SkipEnumerable<TSource> SkipLinq_Custom_Enumerable_DF_NoVirt<TSource>(this List<TSource> source, int count)
{
return new SkipEnumerable<TSource>(source, count);
}
public static SkipEnumerable<TSource> SkipLinq_Custom_Enumerable_DF_NoVirt<TSource>(this SkipEnumerable<TSource> source, int count)
{
return new SkipEnumerable<TSource>(source, count);
}
public static IEnumerable<TSource> SkipLinq_Custom_List<TSource>(this IEnumerable<TSource> source, int count)
{
if (source is IList<TSource>)
{
IList<TSource> list = (IList<TSource>)source;
for (int i = count; i < list.Count; i++)
{
yield return list[i];
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
while (count > 0 && e.MoveNext()) count--;
if (count <= 0)
{
while (e.MoveNext()) yield return e.Current;
}
}
}
}
public static IEnumerable<TSource> SkipLinq_Custom_List_2<TSource>(this List<TSource> source, int count)
{
if (source == null) throw new ArgumentNullException();
using (var e = source.GetEnumerator())
{
var list = source;
for (int i = count; i < list.Count; i++)
{
e.MoveNext();
yield return list[i];
}
}
}
public static IEnumerable<TSource> Where_Custom<TSource>(this List<TSource> source, Func<TSource, bool> predicate)
{
List<TSource> result = new List<TSource>();
foreach (var item in source)
{
if (predicate(item))
result.Add(item);
}
return result;
}
public static IEnumerable<TSource> WhereLinq_Custom_WhereEnumerable<TSource>(this List<TSource> source, Func<TSource, bool> predicate)
{
if (source == null || predicate == null) throw new ArgumentNullException();
return new WhereCustomEnumerable<TSource>(source, predicate);
}
public static WhereCustomEnumerable<TSource>
WhereLinq_Custom_WhereEnumerable_Better<TSource>
(this List<TSource> source, Func<TSource, bool> predicate)
{
if (source == null || predicate == null) throw new ArgumentNullException();
var where = new WhereCustomEnumerable<TSource>(source, predicate);
return where;
}
public static TSource FirstOrDefault<TSource>(
this RefList<TSource> source, Func<TSource, bool> predicate)
{
foreach (var item in source)
{
if (predicate(item))
return item;
}
return default(TSource);
}
public static List<TSource> ToList_Custom<TSource>(this WhereCustomEnumerable<TSource> where)
{
if (where.source == null) throw new ArgumentNullException();
var list = new List<TSource>(where.source.Count);
foreach (var e in where)
{
list.Add(e);
}
return list;
}
public static TSource FirstOrDefault_Custom<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source is List<TSource>)
{
List<TSource> list = (List<TSource>)source;
foreach (var item in list)
{
if (predicate(item)) return item;
}
return default(TSource);
}
foreach (var item in source)
{
if (predicate(item)) return item;
}
return default(TSource);
}
public static TSource FirstOrDefault_Custom<TSource>(this SkipEnumerable<TSource> source)
{
if (source.source == null) throw new ArgumentNullException();
if (source.source.Count > 0)
{
using (var e = source.GetEnumerator())
{
e.MoveNext();
return e.Current;
}
}
return default(TSource);
}
public static TSource FirstOrDefault_Custom2<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw new ArgumentNullException();
using (var e = source.GetEnumerator())
{
e.MoveNext();
return e.Current;
}
throw new ArgumentException();
}
//public static TSource Last<TSource>(this IEnumerable<TSource> source)
//{
// if (source is IList<TSource> listSource)
// {
// return listSource[listSource.Count - 1];
// }
// TSource last = default(TSource);
// foreach (var item in source)
// {
// last = item;
// }
// return last;
//}
//public static TSource Last<TSource>(this IList<TSource> source)
//{
// return source[source.Count - 1];
//}
//public static TSource Last_Custom<TSource>(this IEnumerable<TSource> source)
//{
// if (source is IList<TSource> listSource)
// {
// return listSource[listSource.Count - 1];
// }
//}
}
public readonly struct WhereCustomEnumerable<TSource> : IEnumerable<TSource>
{
public readonly Func<TSource, bool> predicate;
public readonly List<TSource> source;
public WhereCustomEnumerable(List<TSource> source, Func<TSource, bool> predicate)
{
this.predicate = predicate;
this.source = source;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator()
{
return new Enumerator(in this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(in this);
}
IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
{
return new Enumerator(in this);
}
public struct Enumerator : IEnumerator<TSource>
{
readonly List<TSource> source;
readonly Func<TSource, bool> predicate;
private int index;
public Enumerator(in WhereCustomEnumerable<TSource> where)
{
index = -1;
this.source = where.source;
this.predicate = where.predicate;
}
public TSource Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => source[index];
}
object IEnumerator.Current => throw new NotImplementedException();
public void Dispose()
{
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
while (++index < source.Count)
{
if (predicate(source[index]))
return true;
}
return false;
}
public void Reset()
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment