Skip to content

Instantly share code, notes, and snippets.

@thomaslevesque
Last active December 16, 2015 00:29
Show Gist options
  • Save thomaslevesque/5348142 to your computer and use it in GitHub Desktop.
Save thomaslevesque/5348142 to your computer and use it in GitHub Desktop.
void Main()
{
var list1 = Enumerable.Range(0, 10000).Select(i => i.ToString());
var list2 = Enumerable.Range(0, 10000).Select(i => i.ToString());
var list3 = Enumerable.Range(0, 10000).Select(i => i.ToString());
// First run to avoid JIT during the benchmark
list1.ZipOne(list2, list3, Merge).Count();
list1.ZipTwo(list2, list3, Merge).Count();
var stopWatch = new Stopwatch();
TimeSpan t1;
TimeSpan t2;
// declared as int rather than object to avoid boxing
int result;
stopWatch.Start();
for(var i = 0; i < 1000; i++)
result = list1.ZipOne(list2, list3, Merge).Count();
stopWatch.Stop();
t1 = stopWatch.Elapsed.Dump("ZipOne");
stopWatch.Restart();
for(var i = 0; i < 1000; i++)
result = list2.ZipTwo(list2, list3, Merge).Count();
stopWatch.Stop();
t2 = stopWatch.Elapsed.Dump("ZipTwo");
var difference = Math.Abs(t1.Subtract(t2).TotalMilliseconds);
var average = t1.Add(t2).TotalMilliseconds / 2;
(difference / average * 100).Dump("Difference");
}
public object Merge(string s1, string s2, string s3)
{
return new { s1, s2, s3 };
}
// Define other methods and classes here
public static class EnumerableExtensions
{
public static IEnumerable<TResult> ZipOne<TFirst, TSecond, TThird, TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
IEnumerable<TThird> third,
Func<TFirst, TSecond, TThird, TResult> resultSelector )
{
if( first == null )
throw new ArgumentNullException( "first cannot be null" );
if( second == null )
throw new ArgumentNullException( "second cannot be null" );
if( third == null )
throw new ArgumentNullException( "third cannot be null" );
if(resultSelector == null)
throw new ArgumentNullException( "resultSelector cannot be null" );
using ( var iterator1 = first.GetEnumerator() )
using ( var iterator2 = second.GetEnumerator() )
using ( var iterator3 = third.GetEnumerator() )
{
while ( iterator1.MoveNext() && iterator2.MoveNext() && iterator3.MoveNext() )
{
yield return resultSelector(
iterator1.Current,
iterator2.Current,
iterator3.Current );
}
}
}
public static IEnumerable<TResult> ZipTwo<TFirst, TSecond, TThird, TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
IEnumerable<TThird> third,
Func<TFirst, TSecond, TThird, TResult> resultSelector)
{
return first.Zip(second, (f, s) => new { f, s })
.Zip(third, (fs, t) => resultSelector(fs.f, fs.s, t));
}
}
Copy link

ghost commented Apr 9, 2013

Ah I love LinqPad :)

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