Skip to content

Instantly share code, notes, and snippets.

@jcdickinson
Last active September 21, 2016 09:16
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 jcdickinson/e19cc76fef71a982d24ae4a7c7dc18b5 to your computer and use it in GitHub Desktop.
Save jcdickinson/e19cc76fef71a982d24ae4a7c7dc18b5 to your computer and use it in GitHub Desktop.
Attempt at JIT-optimized Linq Where
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace EnumerableTest
{
class Program
{
static void Main(string[] args)
{
var nums = new[] { 1, 2, 3, 4, 5, 6 };
var val = 0;
foreach (var num in Enumerable2.Where(nums, x => x % 2 == 0))
val += num;
Console.WriteLine(val);
Debugger.Launch(); // Dissasembly
Console.ReadLine();
}
}
static class Enumerable2
{
public struct WhereEnumerator<TValue> : IEnumerator<TValue>
{
private readonly Func<TValue, bool> _fn;
private readonly TValue[] _enumerable;
private int _current;
public TValue Current => _enumerable[_current];
object IEnumerator.Current => _enumerable[_current];
public WhereEnumerator(TValue[] enumerator, Func<TValue, bool> fn)
{
_enumerable = enumerator;
_fn = fn;
_current = -1;
}
public void Dispose() { }
public void Reset() => _current = -1;
public bool MoveNext()
{
return ++_current < _enumerable.Length;
}
}
public struct WhereEnumerable<TEnumerable, TValue> : IEnumerable<TValue>
{
private readonly Func<TValue, bool> _fn;
private readonly TValue[] _enumerable;
public WhereEnumerable(TValue[] enumerable, Func<TValue, bool> fn)
{
_enumerable = enumerable;
_fn = fn;
}
public WhereEnumerator<TValue> GetEnumerator() => new WhereEnumerator<TValue>(_enumerable, _fn);
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static WhereEnumerable<IEnumerable<TValue>, TValue> Where<TValue>(this TValue[] enumerable, Func<TValue, bool> fn)
{
return new WhereEnumerable<IEnumerable<TValue>, TValue>(enumerable, fn);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace EnumerableTest
{
class Program
{
static void Main(string[] args)
{
var nums = new[] { 1, 2, 3, 4, 5, 6 };
var val = 0;
foreach (var num in Enumerable2.Where(nums, x => x % 2 == 0))
val += num;
Console.WriteLine(val);
Debugger.Launch(); // Dissasembly
Console.ReadLine();
}
}
static class Enumerable2
{
public struct WhereEnumerator<TValue> : IEnumerator<TValue>
{
private readonly Func<TValue, bool> _fn;
private readonly IEnumerator<TValue> _enumerator;
public TValue Current => _enumerator.Current;
object IEnumerator.Current => _enumerator.Current;
public WhereEnumerator(IEnumerator<TValue> enumerator, Func<TValue, bool> fn)
{
_enumerator = enumerator;
_fn = fn;
}
public void Dispose() => _enumerator.Dispose();
public void Reset() => _enumerator.MoveNext();
public bool MoveNext()
{
while (_enumerator.MoveNext())
{
if (_fn(_enumerator.Current))
return true;
}
return false;
}
}
public struct WhereEnumerable<TEnumerable, TValue> : IEnumerable<TValue>
where TEnumerable : IEnumerable<TValue>
{
private readonly Func<TValue, bool> _fn;
private readonly TEnumerable _enumerable;
public WhereEnumerable(TEnumerable enumerable, Func<TValue, bool> fn)
{
_enumerable = enumerable;
_fn = fn;
}
public WhereEnumerator<TValue> GetEnumerator() => new WhereEnumerator<TValue>(_enumerable.GetEnumerator(), _fn);
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static WhereEnumerable<IEnumerable<TValue>, TValue> Where<TValue>(this IEnumerable<TValue> enumerable, Func<TValue, bool> fn)
{
return new WhereEnumerable<IEnumerable<TValue>, TValue>(enumerable, fn);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment