Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialElshad Shabanov
2,890 PointsIn my test, Concat + Distinct is way faster than Concat alone or Union
In Linq chapter - Which is Faster? Union or Concat, I've got different results. Here is my code:
//
var listA = Enumerable.Range(0, 100000);
var listB = Enumerable.Range(50000, 100000);
Stopwatch stopWatch = new Stopwatch();
//Union operation
stopWatch.Start();
var listUni = listA.Union(listB);
stopWatch.Stop();
var unionTicks = stopWatch.ElapsedTicks;
//Concat operation
stopWatch.Restart();
var listCon = listA.Concat(listB);
stopWatch.Stop();
var concatTicks = stopWatch.ElapsedTicks;
//Concat and Distinct operations
stopWatch.Restart();
var listConDist = listA.Concat(listB).Distinct();
stopWatch.Stop();
var conDisTicks = stopWatch.ElapsedTicks;
Console.WriteLine($"Union: {unionTicks}");
Console.WriteLine($"Concat: {concatTicks}");
Console.WriteLine($"ConDist: {conDisTicks}");
/* output:
Union: 3049
Concat: 1076
ConDist: 37
*/
2 Answers
James Churchill
Treehouse TeacherElshad,
Great catch! Thanks for taking the time to report this issue.
There's something else also at play here; both in your code example and the example that's shown in the video. What execution times do you get if you add to the end of your queries a call to either the ToList
or Count
method?
Here's an example using the Count
method:
var listA = Enumerable.Range(0, 100000);
var listB = Enumerable.Range(50000, 100000);
Stopwatch stopWatch = new Stopwatch();
// Union operation
stopWatch.Start();
var listUniCount = listA.Union(listB).Count();
Console.WriteLine(listUniCount);
stopWatch.Stop();
var unionTicks = stopWatch.ElapsedTicks;
// Concat operation
stopWatch.Restart();
var listConCount = listA.Concat(listB).Count();
Console.WriteLine(listConCount);
stopWatch.Stop();
var concatTicks = stopWatch.ElapsedTicks;
// Concat and Distinct operations
stopWatch.Restart();
var listConDistCount = listA.Concat(listB).Distinct().Count();
Console.WriteLine(listConDistCount);
stopWatch.Stop();
var conDisTicks = stopWatch.ElapsedTicks;
Console.WriteLine($"Union: {unionTicks}");
Console.WriteLine($"Concat: {concatTicks}");
Console.WriteLine($"ConDist: {conDisTicks}");
You should notice substantially longer execution times. Why is that? Well, without calling a method like ToList
or Count
that requires the query to be enumerated in order to return a result, LINQ queries won't be enumerated until absolutely necessary. This is called "deferred execution".
For more information, see: https://msdn.microsoft.com/en-us/library/bb738633(v=vs.110).aspx
Back to your original point though: even with the longer execution times, Concat+Distinct is considerably faster than Union. We're working on a fix to the course, so we hope to have this issue resolved sometime soon.
Thanks ~James
Kevin Gates
15,053 PointsMine shows Union faster by 381 ticks, but I'm not showing the same code you have above.
Mine is:
using System;
using System.Diagnostics;
using System.Linq;
namespace UnionVsConcat
{
class Program
{
public static void Main(string[] args)
{
var listA = Enumerable.Range(0,100000);
var listB = Enumerable.Range(50000, 100000);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var listC = listA.Union(listB);
stopwatch.Stop();
var unionTicks = stopwatch.ElapsedTicks;
stopwatch.Restart();
var listD = listA.Concat(listB).Distinct();
stopwatch.Stop();
var concatTicks = stopwatch.ElapsedTicks;
Console.WriteLine(string.Format("Union took {0} ticks", unionTicks));
Console.WriteLine(string.Format("Concat took {0} ticks", concatTicks));
if ( unionTicks > concatTicks)
{
Console.WriteLine("Concat is faster by {0}", (unionTicks - concatTicks));
}
else if ( concatTicks > unionTicks)
{
Console.WriteLine("Union is faster by {0}", (concatTicks - unionTicks));
}
}
}
}