第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在LINQ查詢中調(diào)用ToList()或ToArray()會更好嗎?

在LINQ查詢中調(diào)用ToList()或ToArray()會更好嗎?

泛舟湖上清波郎朗 2019-08-06 14:38:36
在LINQ查詢中調(diào)用ToList()或ToArray()會更好嗎?我經(jīng)常遇到我想在我聲明它的地方評估查詢的情況。這通常是因為我需要多次迭代它并且計算起來很昂貴。例如:string raw = "...";var lines = (from l in raw.Split('\n')              let ll = l.Trim()              where !string.IsNullOrEmpty(ll)              select ll).ToList();這很好用。但是,如果我不打算修改結(jié)果,那么我不妨打電話給ToArray()而不是ToList()。我想知道是否ToArray()通過第一次調(diào)用實現(xiàn),ToList()因此內(nèi)存效率低于僅調(diào)用ToList()。我瘋了嗎?我應該只是打電話ToArray()- 安全且安全地知道內(nèi)存不會被分配兩次嗎?
查看完整描述

3 回答

?
叮當貓咪

TA貢獻1776條經(jīng)驗 獲得超12個贊

除非您只需要一個數(shù)組來滿足其他約束,否則您應該使用它ToList。在大多數(shù)情況下ToArray會分配更多的內(nèi)存ToList。

兩者都使用數(shù)組進行存儲,但ToList具有更靈活的約束。它需要數(shù)組至少與集合中元素的數(shù)量一樣大。如果陣列較大,那不是問題。但是,ToArray需要將數(shù)組的大小精確地調(diào)整為元素的數(shù)量。

為了滿足這種約束,ToArray通常會進行一次分配ToList。一旦它有一個足夠大的數(shù)組,它就會分配一個完全正確大小的數(shù)組,并將元素復制回該數(shù)組。唯一能避免這種情況的是當數(shù)組的增長算法恰好與需要存儲的元素數(shù)量一致時(絕對是少數(shù))。

編輯

有幾個人問我在List<T>數(shù)值中有多余的未使用內(nèi)存的后果。

這是一個有效的問題。如果創(chuàng)建的集合是長期存在的,在創(chuàng)建后永遠不會被修改并且很有可能在Gen2堆中著陸,那么您可能最好先采取額外的分配ToArray。

總的來說,雖然我發(fā)現(xiàn)這是罕見的情況。更常見的是看到很多ToArray調(diào)用立即傳遞給其他短暫的內(nèi)存使用,在這種情況下ToList顯然更好。

這里的關(guān)鍵是剖析,剖析,然后再詳細介紹一些。


查看完整回答
反對 回復 2019-08-06
?
ibeautiful

TA貢獻1993條經(jīng)驗 獲得超6個贊

性能差異將是微不足道的,因為它List<T>是作為動態(tài)大小的陣列實現(xiàn)的。調(diào)用ToArray()(使用內(nèi)部Buffer<T>類來增長數(shù)組)或ToList()(調(diào)用List<T>(IEnumerable<T>)構(gòu)造函數(shù))將最終成為將它們放入數(shù)組并增長數(shù)組直到它適合所有數(shù)組的問題。

如果您希望具體確認這一事實,請查看Reflector中相關(guān)方法的實現(xiàn) - 您將看到它們歸結(jié)為幾乎完全相同的代碼。


查看完整回答
反對 回復 2019-08-06
?
慕桂英4014372

TA貢獻1871條經(jīng)驗 獲得超13個贊

其他(好)答案集中在將發(fā)生的微觀性能差異上。


此信息僅僅是一個補充提語義差別之間存在IEnumerator<T>(產(chǎn)生由陣列T[])相比于由一個返回List<T>。


通過示例最佳說明:


IList<int> source = Enumerable.Range(1, 10).ToArray();  // try changing to .ToList()


foreach (var x in source)

{

  if (x == 5)

    source[8] *= 100;

  Console.WriteLine(x);

}

上面的代碼將運行,沒有異常并產(chǎn)生輸出:


1

2

3

4

6

7

8

900

10

這表明IEnumarator<int>由an返回的數(shù)據(jù)int[]不會跟蹤自創(chuàng)建枚舉器以來數(shù)組是否已被修改。


請注意,我將局部變量聲明source為IList<int>。通過這種方式,我確保C#編譯器不會將foreach語句優(yōu)化為等同于for (var idx = 0; idx < source.Length; idx++) { /* ... */ }循環(huán)的東西。如果我使用C#編譯器可能會這樣做var source = ...;。在我當前版本的.NET框架中,這里使用的實際枚舉器是非公共引用類型,System.SZArrayHelper+SZGenericArrayEnumerator`1[System.Int32]但當然這是一個實現(xiàn)細節(jié)。


現(xiàn)在,如果我改變.ToArray()成.ToList(),我只得到:


1

2

3

4

隨后是一個System.InvalidOperationException爆炸性的說法:


收集被修改; 枚舉操作可能無法執(zhí)行。


在這種情況下,底層枚舉器是public mutable value-type System.Collections.Generic.List`1+Enumerator[System.Int32](IEnumerator<int>在這種情況下,盒子裝在盒子里,因為我使用IList<int>)。


總之,由枚舉器生成的枚舉器List<T>會跟蹤列表在枚舉期間是否發(fā)生更改,而生成的枚舉T[]器則不會。因此,在.ToList()和之間選擇時要考慮這種差異.ToArray()。


人們經(jīng)常添加一個額外的 .ToArray()或.ToList()繞過一個集合來跟蹤它是否在枚舉器的生命周期中被修改。


(如果有人想知道如何在List<>跟蹤上收集是否被修改,有一個私人領(lǐng)域_version在這個類,這是每次改變的List<>更新。)


查看完整回答
反對 回復 2019-08-06
  • 3 回答
  • 0 關(guān)注
  • 1287 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號