3 回答

TA貢獻(xiàn)1890條經(jīng)驗(yàn) 獲得超9個(gè)贊
保證非常非常少,但有一些優(yōu)化:
使用索引訪問擴(kuò)展方法,比如
ElementAt
,Skip
,Last
或者LastOrDefault
,將檢查底層式工具與否IList<T>
,讓你得到O(1)訪問,而不是O(N)。該
Count
方法檢查ICollection
實(shí)現(xiàn),以便該操作是O(1)而不是O(N)。Distinct
,GroupBy
Join
我相信set-aggregation方法(Union
,Intersect
和Except
)也使用散列,所以它們應(yīng)該接近O(N)而不是O(N2)。Contains
檢查ICollection
實(shí)現(xiàn),因此如果底層集合也是O(1),它可能是O(1),例如aHashSet<T>
,但這取決于實(shí)際的數(shù)據(jù)結(jié)構(gòu),并且不能保證。散列集覆蓋了該Contains
方法,這就是它們?yōu)镺(1)的原因。OrderBy
方法使用穩(wěn)定的快速排序,因此它們是O(N log N)平均情況。
我認(rèn)為這涵蓋了大多數(shù)(如果不是全部)內(nèi)置擴(kuò)展方法。實(shí)際保證很少; Linq本身將嘗試?yán)酶咝У臄?shù)據(jù)結(jié)構(gòu),但編寫可能效率低下的代碼并不是免費(fèi)的。

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊
我早就知道如果枚舉是一個(gè).Count()
返回。.Count
IList
但是我總是有點(diǎn)疲憊有關(guān)Set操作的運(yùn)行時(shí)間復(fù)雜度:.Intersect()
,.Except()
,.Union()
。
這是針對(duì).Intersect()
(評(píng)論我的)反編譯的BCL(.NET 4.0 / 4.5)實(shí)現(xiàn):
private static IEnumerable<TSource> IntersectIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer){ Set<TSource> set = new Set<TSource>(comparer); foreach (TSource source in second) // O(M) set.Add(source); // O(1) foreach (TSource source in first) // O(N) { if (set.Remove(source)) // O(1) yield return source; }}
結(jié)論:
性能是O(M + N)
當(dāng)集合已經(jīng)設(shè)置時(shí),實(shí)現(xiàn)不會(huì)占用優(yōu)勢(shì)。(它可能不一定是直截了當(dāng)?shù)?,因?yàn)槭褂眠^的也需要匹配。)
IEqualityComparer<T>
為了完整起見,這里都為實(shí)現(xiàn).Union()
和.Except()
。
擾流板警報(bào):它們也具有O(N + M) 復(fù)雜度。
private static IEnumerable<TSource> UnionIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer){ Set<TSource> set = new Set<TSource>(comparer); foreach (TSource source in first) { if (set.Add(source)) yield return source; } foreach (TSource source in second) { if (set.Add(source)) yield return source; }}private static IEnumerable<TSource> ExceptIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer){ Set<TSource> set = new Set<TSource>(comparer); foreach (TSource source in second) set.Add(source); foreach (TSource source in first) { if (set.Add(source)) yield return source; }}

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
所有你能真正依賴的是,Enumerable方法是針對(duì)一般情況編寫的,不會(huì)使用樸素算法??赡苡械谌降臇|西(博客等)描述了實(shí)際使用的算法,但這些并不是官方的,也不是STL算法所保證的。
為了說明,這里是Enumerable.Count
來自System.Core 的反映源代碼(由ILSpy提供):
// System.Linq.Enumerablepublic static int Count<TSource>(this IEnumerable<TSource> source){ checked { if (source == null) { throw Error.ArgumentNull("source"); } ICollection<TSource> collection = source as ICollection<TSource>; if (collection != null) { return collection.Count; } ICollection collection2 = source as ICollection; if (collection2 != null) { return collection2.Count; } int num = 0; using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; }}
正如您所看到的,它需要付出一些努力來避免簡(jiǎn)單地枚舉每個(gè)元素的天真解決方案。
- 3 回答
- 0 關(guān)注
- 798 瀏覽
添加回答
舉報(bào)