亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

調用ToList()會對性能產生影響嗎?

調用ToList()會對性能產生影響嗎?

C#
慕村9548890 2019-11-11 10:25:49
使用時ToList(),是否需要考慮對性能的影響?我正在編寫一個查詢來從目錄(即查詢)中檢索文件:string[] imageArray = Directory.GetFiles(directory);但是,由于我想與之合作List<>,所以我決定投入...List<string> imageList = Directory.GetFiles(directory).ToList();因此,在決定進行這種轉換時是否應該考慮某種性能影響?或者僅在處理大量文件時才考慮?這是微不足道的轉換嗎?
查看完整描述

3 回答

?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

IEnumerable.ToList()

是的,IEnumerable<T>.ToList()確實會對性能產生影響,盡管可能只需要關注性能關鍵的操作,但它是O(n)操作。


該ToList()操作將使用List(IEnumerable<T> collection)構造函數。這個構造函數必須復制數組(通常是IEnumerable<T>),否則將來對原始數組的修改T[]也將在源上更改,這通常是不希望的。


我想重申的是,這只會對龐大的列表有所作為,復制內存塊是一項非??焖俚牟僮?。


方便的提示,AsvsTo

您會在LINQ中注意到有幾種以As(如AsEnumerable())和To(如ToList())開頭的方法。開頭的方法To需要進行上述轉換(即可能會影響性能),而開頭的方法As則不需要,只需要進行一些強制轉換或簡單操作即可。


有關的其他詳細信息 List<T>

List<T>如果您有興趣,這里有一些工作原理的詳細信息:)


A List<T>還使用一種稱為動態數組的結構,該結構需要按需調整大小,此調整大小事件將舊數組的內容復制到新數組。因此,它從很小的地方開始,并在需要時增加尺寸。


這是的Capacity和Count屬性之間的區別List<T>。Capacity指的是幕后數組的大小,Count是其中的項目數List<T>始終為<= Capacity。因此,當將一項添加到列表中時,將其增加到之后Capacity,的大小將List<T>增加一倍,并復制數組。


查看完整回答
反對 回復 2019-11-11
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

調用toList()會對性能產生影響嗎?


當然是。從理論上講i++,它甚至會對性能產生影響,可能會使程序變慢幾格。


怎么.ToList辦?


調用時.ToList,代碼將調用Enumerable.ToList()作為擴展方法的return new List<TSource>(source)。在相應的構造函數中,在最壞的情況下,它將遍歷item容器并將它們一個接一個地添加到新容器中。因此,它的行為對性能幾乎沒有影響。成為應用程序的性能瓶頸是不可能的。


問題中的代碼有什么問題


Directory.GetFiles遍歷該文件夾并將所有文件的名稱立即返回到內存中,這有可能會導致string []占用大量內存,從而減慢一切。


那應該怎么辦


這取決于。如果您(以及您的業務邏輯)保證該文件夾中的文件數量始終很小,那么該代碼是可以接受的。但是仍然建議使用懶惰版本:Directory.EnumerateFiles在C#4中。這更像是查詢,不會立即執行,您可以在其上添加更多查詢,例如:


Directory.EnumerateFiles(myPath).Any(s => s.Contains("myfile"))

一旦找到名稱包含“ myfile”的文件,它將立即停止搜索路徑。這顯然具有更好的性能.GetFiles。


查看完整回答
反對 回復 2019-11-11
?
www說

TA貢獻1775條經驗 獲得超8個贊

調用toList()會對性能產生影響嗎?

就在這里。使用擴展方法Enumerable.ToList()將從源集合構造一個新List<T>對象,IEnumerable<T>這當然會對性能產生影響。

但是,了解List<T>可能會幫助您確定性能影響是否重大。

List<T>使用數組(T[])存儲列表的元素。數組一旦分配就無法擴展,因此List<T>將使用超大數組來存儲列表中的元素。當List<T>增長超出基礎數組的大小時,必須分配新數組,并且必須在列表可以增長之前將舊數組的內容復制到新的較大數組。

List<T>從中構造新對象時,IEnumerable<T>有兩種情況:

  1. 源集合的實現ICollection<T>:然后ICollection<T>.Count用于獲取源集合的確切大小,并在使用ICollection<T>.CopyTo()。將源集合的所有元素復制到支持數組之前分配一個匹配的支持數組。此操作非常有效,可能會映射到某些CPU指令以復制內存塊。但是,就性能而言,新陣列需要內存,復制所有元素需要CPU周期。

  2. 否則源集合的大小是未知的,并且使用的枚舉器IEnumerable<T>將每個源元素一次添加到新元素中List<T>。最初,支持數組為空,并創建了大小為4的數組。然后,當此數組太小時,其大小將增加一倍,因此后備數組將像4、8、16、32等那樣增長。每當后備數組增長時,都必須重新分配它,并且必須復制到目前為止存儲的所有元素。與可以立即創建正確大小的數組的第一種情況相比,此操作的成本要高得多。

    另外,如果您的源集合包含33個元素,則該列表最終將使用64個元素的數組浪費一些內存。

在您的情況下,源集合是一個實現的數組,ICollection<T>因此,除非源數組很大,否則您不必擔心性能影響。調用ToList()將只復制源數組并將其包裝在一個List<T>對象中。即使是第二種情況的性能,也不必為小收藏而擔心。


查看完整回答
反對 回復 2019-11-11
  • 3 回答
  • 0 關注
  • 1123 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號