-
-
Save jcdickinson/e19cc76fef71a982d24ae4a7c7dc18b5 to your computer and use it in GitHub Desktop.
Attempt at JIT-optimized Linq Where
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 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); | |
} | |
} | |
} |
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 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