2011-05-11 31 views
7

我正在製作一個視頻遊戲,其中性能至關重要。更快的替代品.Distinct()

我使用.Distinct()擴展方法從列表中獲取唯一值。 有沒有更快的方法來做到這一點? (即使這意味着有更多的代碼行)

+0

這將有助於有更多的背景... – soandos

+1

你需要更多的細節 - 你有控制如何生成列表?你可以做得更好,如果你從來沒有在列表中插入重複的元素...... –

+1

'.Distinct' _is_更快。你有個人簡介嗎? – SLaks

回答

19

.DistinctO(n)調用。
你不能比這更快。

但是,您應該確保您的GetHashCode(以及較小程度的Equals)儘可能快。

根據您的情況,您可以用HashSet<T>代替List<T>,這樣可以防止首先插入重複項。 (還有O(1)插入)

但是,始終在剖析你的代碼之前,跳到關於什麼需要更快的結論

+4

+1對於「在跳到必須更快的結論之前總是剖析你的代碼」 –

4

是否必須是List?

是否可以從List切換到HashSet? HashSet首先防止對象被多次插入到列表中,所以Distinct已經完成。

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在最後調整大小而不分配。這最終顯着更快。

其他海報可能是正確的,但您可以通過其他方式實現此目標,例如首先使用哈希集合,或者保持平行集合,其中只包含不同元素。在插入/移除時抵消小額費用,以便根本不需要時間來獲得不同的組合。