更快的替代品.Distinct()

时间:2011-05-11 21:43:04

标签: c# .net linq

我正在制作一款性能至关重要的视频游戏。

我正在使用.Distinct()扩展方法从List中获取唯一值。 有更快的方法吗? (即使这意味着有更多的代码行)

3 个答案:

答案 0 :(得分:22)

.DistinctO(n)电话 你不能比这更快。

但是,您应确保GetHashCode(以及在较小程度上Equals)尽可能快。

根据您的情况,您可以将List<T>替换为HashSet<T>,这样可以防止首先插入重复项。 (但O(1)插入)

但是,在得出有关需要更快的内容的结论之前,始终对代码进行分析

答案 1 :(得分:4)

是否必须是列表?

是否可以从List切换到HashSet? HashSet可以防止对象首先插入到列表中多次,因此Distinct已经完成。

答案 2 :(得分:0)

如果你可以做到与众不同,你可以通过首先使用Array.Sort然后:

来快速完成并且零分配
 TSource oldV = source[0];
 int pos = 1;
 for (int i = 1; i < source.Count; i++)
 {
     var newV = source[i];
     source[pos] = newV;
     if (!eqComparer.Equals(newV, oldV))
     {
        pos++;
     }                
     oldV = newV;
 }
 //pos now == the new size of the array

然后你必须跟踪现在较小的数组大小,或者使用Array.resize(但这将分配一个新的数组)

或者,如果您使用List<T>执行相同的方法,则可以在结尾调用RemoveRange以在不分配的情况下调整其大小。这最终会明显加快。

其他海报可能是正确的,但您可以通过其他方式实现此目标,例如首先使用哈希集,或保持并行集合,其中一直只包含不同的元素。在插入/移除时抵消小的成本,因此根本不需要时间来获得不同的集合。