我正在制作一款性能至关重要的视频游戏。
我正在使用.Distinct()扩展方法从List中获取唯一值。 有更快的方法吗? (即使这意味着有更多的代码行)
答案 0 :(得分:22)
.Distinct
是O(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
以在不分配的情况下调整其大小。这最终会明显加快。
其他海报可能是正确的,但您可以通过其他方式实现此目标,例如首先使用哈希集,或保持并行集合,其中一直只包含不同的元素。在插入/移除时抵消小的成本,因此根本不需要时间来获得不同的集合。