C# 从性能上看,哪一个更好:多个相似列表的并集,还是在一个包含大量重复项的大列表上的不同列表?
一点背景: 我正在制作一个小应用程序来演示LINQ的使用,所以我应该主要使用LINQ方法。该应用程序将显示一些有关电影和电视节目的信息,并根据过滤器提出建议 我上过三节课:电视剧、季和集。电视节目包含季节列表,季节包含插曲列表。该集包含该集演员的名单。我想在TvShow类中创建一个方法,该方法根据每集的演员列表返回完整的演员列表 我决定使用Union或Distinct,但我不确定哪种方法在性能方面更好,因为我认为这是在这个例子中选择一种方法而不是另一种方法的唯一原因(我知道在这么小的应用程序上性能并不是一个真正的问题,但我想知道在更大的范围内这将如何表现) 以下是两种方法:C# 从性能上看,哪一个更好:多个相似列表的并集,还是在一个包含大量重复项的大列表上的不同列表?,c#,linq,C#,Linq,一点背景: 我正在制作一个小应用程序来演示LINQ的使用,所以我应该主要使用LINQ方法。该应用程序将显示一些有关电影和电视节目的信息,并根据过滤器提出建议 我上过三节课:电视剧、季和集。电视节目包含季节列表,季节包含插曲列表。该集包含该集演员的名单。我想在TvShow类中创建一个方法,该方法根据每集的演员列表返回完整的演员列表 我决定使用Union或Distinct,但我不确定哪种方法在性能方面更好,因为我认为这是在这个例子中选择一种方法而不是另一种方法的唯一原因(我知道在这么小的应用程序上性
public List<Actor> AllCast()
{
List<Actor> actors = new List<Actor>();
foreach (Season s in seasons)
{
s.Episodes.ForEach(e => actors.AddRange(e.Cast));
}
return actors.Distinct().ToList();
}
public List AllCast()
{
列表参与者=新列表();
foreach(季节中的季节s)
{
s、 Spices.ForEach(e=>actors.AddRange(e.Cast));
}
返回actors.Distinct().ToList();
}
或
public List AllCast()
{
列表参与者=新列表();
foreach(季节中的季节s)
{
s、 Spices.ForEach(e=>actors.AddRange(actors.Union(e.Cast));
}
返回演员;
}
我的想法是:继续在一个大列表中添加多个列表,然后遍历这个巨大的列表并只返回不同的值是更好的,还是最好遍历一个小列表和一个不断增长的列表并比较值以找到一个联合(我假设联合就是这样找到它的结果的),然后将其添加到已经唯一的列表中
另外,我知道HashSet,但我真的很想在这里使用LINQ,因为这是我项目的目的 既然使用LINQ是您项目的一部分,为什么不使用此纯LINQ方法:
public List<Actor> AllCast()
{
List<Actor> actors = seasons
.SelectMany(season => season.Episodes.SelectMany(episode => episode.Cast))
.Distinct()
.ToList();
return actors;
}
public List AllCast()
{
演员名单=季节
.SelectMany(季节=>季节.剧集.SelectMany(剧集=>剧集.演员阵容))
.Distinct()
.ToList();
返回演员;
}
我想这也是最有效的方法之一。它将所有包含的对象展平为一个大序列,然后只使用一次
Distinct
(使用一个集合)。非LINQ方法是使用嵌套的foreach
循环,将演员添加到HashSet
中,然后调用set.ToList()
第二种方法需要为每一季内部构建一个新的HashSet
,将这一季的演员与我们之前见过的所有演员进行比较——我认为这比对所有演员进行一次检查要慢,将他们放在一组中以获得独特性
我会使用SelectMany
两次,以在LINQ中实现这一切:
public List<Actor> AllCast() =>
seasons // All seasons
.SelectMany(s => s.Episodes) // All episodes as a flat sequence
.SelectMany(e => e.Cast) // All actors as a flat sequence
.Distinct() // Distinct
.ToList();
public List AllCast()=>
四季//四季
.SelectMany(s=>s.scents)//将所有剧集作为一个平面序列
.SelectMany(e=>e.Cast)//将所有参与者作为一个平面序列
.Distinct()//Distinct
.ToList();
除此之外,您还可以使用SelectMany
提供很多帮助:回归季。SelectMany(s=>s.scents)。SelectMany(e=>e.Cast)。Distinct().ToList()代码>现在,您是否有足够的数据可以测量这是否太慢?你能创建这样的数据吗?这不是一个重复的或至少是相关的问题吗@JonSkeet不幸的是,我目前没有任何数据,所以我无法测试它:/I我计划稍后添加一些数据,只是为了得到演示结果,但不足以实际测试任何内容,这就是为什么我在这里问,以防有人已经对此进行了研究。这主要是我在学习LINQ时要做的一个项目,它实际上与性能无关,但我想在做更深入的研究时也考虑这些事情,所以我在未来意识到了这一点。我添加了我自己的答案,作为你的一个小变种-我将做两个“顶级”选择多个呼叫,而不是一个嵌套在另一个呼叫中。我怀疑它的效率会大大提高或降低。我还没有研究过很多,谢谢你给我展示了一种比我上面尝试过的更好的方法!我不知道它在后台使用HashSet,谢谢!我还没有探索过很多,所以谢谢你给我指出,这是更好的,因为它是纯LINQ!
public List<Actor> AllCast() =>
seasons // All seasons
.SelectMany(s => s.Episodes) // All episodes as a flat sequence
.SelectMany(e => e.Cast) // All actors as a flat sequence
.Distinct() // Distinct
.ToList();