Last active
December 16, 2015 00:29
-
-
Save thomaslevesque/5348142 to your computer and use it in GitHub Desktop.
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
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)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ah I love LinqPad :)