Skip to content

Instantly share code, notes, and snippets.

@markrendle
Created December 9, 2011 10:49
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 markrendle/1451071 to your computer and use it in GitHub Desktop.
Save markrendle/1451071 to your computer and use it in GitHub Desktop.
Single-element enumerable comparison
namespace EnumerableOfOneTest
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Diagnostics;
class Program
{
static void Main()
{
int n = 0;
var watch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
n += GetOneCustomClass().Single();
}
watch.Stop();
Console.WriteLine("Custom class: {0} ({1:##,#})", watch.Elapsed, n);
n = 0;
watch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
n += GetOneIterator().Single();
}
watch.Stop();
Console.WriteLine("Iterator : {0} ({1:##,#})", watch.Elapsed, n);
n = 0;
watch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
n += GetOneArray().Single();
}
watch.Stop();
Console.WriteLine("Array : {0} ({1:##,#})", watch.Elapsed, n);
}
private static IEnumerable<int> GetOneCustomClass()
{
return new SingleEnumerable<int>(1);
}
private static IEnumerable<int> GetOneArray()
{
return new[] {1};
}
private static IEnumerable<int> GetOneIterator()
{
yield return 1;
}
}
class SingleEnumerable<T> : IEnumerable<T>
{
private readonly T _value;
public SingleEnumerable(T value)
{
_value = value;
}
public IEnumerator<T> GetEnumerator()
{
return new SingleEnumerator(_value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
class SingleEnumerator : IEnumerator<T>
{
private readonly T _value;
private int _state;
public SingleEnumerator(T value)
{
_value = value;
}
public void Dispose()
{
}
public bool MoveNext()
{
// Can only do this once (NB: post-fix ++ returns previous value of _state)
return _state++ == 0;
}
public void Reset()
{
_state = 0;
}
public T Current
{
get
{
// Only valid after a single MoveNext call()
if (_state != 1) throw new InvalidOperationException();
return _value;
}
}
object IEnumerator.Current
{
get { return Current; }
}
}
}
}
@markrendle
Copy link
Author

Timings on my laptop:

Custom class: 00:00:00.4003948 (10,000,000)
Iterator : 00:00:00.5607078 (10,000,000)
Array : 00:00:02.1428748 (10,000,000)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment