Eps said:
Hmmm, I haven't had a chance to test this yet but I think I know whats
going on.
Where the album is not set (String.IsNullOrEmpty) I put in "Unknown
Album". Obviously the query considers all these audio files (and there
will be a significant number of them) as a part of the same album.
Even so it shouldn't be a problem.
Here's a complete program which generates 100,000 tracks and one album
with 1,000 tracks including 5 artists. It counts those 5 distinct
artists in 67ms on my box. That's pretty clear evidence to me that
something is going on beyond what you're aware of. It would be worth
getting to the bottom of that, as it may bite you later on - right now
you've got (I would imagine) a reasonably straightforward situation to
diagnose. The next symptom of the same problem could be much harder to
track down.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
public class Track
{
public string Artist { get; set; }
public Album Album { get; set; }
public static Track GenerateRandom()
{
return new Track
{
Album = new Album(),
Artist = GenerateRandomString()
};
}
static Random rng = new Random();
static string GenerateRandomString()
{
StringBuilder builder = new StringBuilder(15);
for (int i=0; i < 15; i++)
{
builder.Append((char)(rng.Next(26)+'A'));
}
return builder.ToString();
}
}
public class Album
{
}
public static class Test
{
static void Main()
{
// First generate lots of random tracks
List<Track> tracks = new List<Track>();
for (int i=0; i < 100000; i++)
{
tracks.Add(Track.GenerateRandom());
}
string[] artists = { "Mike Rutherfield", "Phil Collins",
"Tony Banks", "Peter Gabriel", "Steve Hackett" };
// Now make 1,000 (or thereabouts) of them belong to one album.
// Give each of them one of our 5 artists
Album picked = new Album();
Random rng = new Random();
for (int i = 0; i < 1000; i++)
{
Track track = tracks[rng.Next(tracks.Count)];
track.Album = picked;
track.Artist = artists[rng.Next(artists.Length)];
}
Console.WriteLine("Finding the distinct count...");
Stopwatch sw = Stopwatch.StartNew();
int count = tracks.Where(track => track.Album == picked)
.Select(track => track.Artist)
.Distinct()
.Count();
sw.Stop();
Console.WriteLine("Found {0} distinct artists in {1}ms",
count, sw.ElapsedMilliseconds);
}
}
I could combine your code with mine, do something like....
this.Where(p => p.Album == AnAudioFileObject.Album)
.Select(s => s.Artist)
.Distinct().Take(10).Any()
This still isn't foolproof, there could be an album with 10 tracks by
one artist and 1 track (or more) by another. But this should be good
enough, I will test it and post the results.
No, it was already foolproof beforehand. You only need Take(1), because
Take(1).Any() is the equivalent of Count() > 1. The important point is
that I put the Take(1) *after* the Distinct() whereas you put it
*before*.