3 回答

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>增加一倍,并復制數組。

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。

TA貢獻1775條經驗 獲得超8個贊
調用toList()會對性能產生影響嗎?
就在這里。使用擴展方法Enumerable.ToList()
將從源集合構造一個新List<T>
對象,IEnumerable<T>
這當然會對性能產生影響。
但是,了解List<T>
可能會幫助您確定性能影響是否重大。
List<T>
使用數組(T[]
)存儲列表的元素。數組一旦分配就無法擴展,因此List<T>
將使用超大數組來存儲列表中的元素。當List<T>
增長超出基礎數組的大小時,必須分配新數組,并且必須在列表可以增長之前將舊數組的內容復制到新的較大數組。
List<T>
從中構造新對象時,IEnumerable<T>
有兩種情況:
源集合的實現
ICollection<T>
:然后ICollection<T>.Count
用于獲取源集合的確切大小,并在使用ICollection<T>.CopyTo()
。將源集合的所有元素復制到支持數組之前分配一個匹配的支持數組。此操作非常有效,可能會映射到某些CPU指令以復制內存塊。但是,就性能而言,新陣列需要內存,復制所有元素需要CPU周期。否則源集合的大小是未知的,并且使用的枚舉器
IEnumerable<T>
將每個源元素一次添加到新元素中List<T>
。最初,支持數組為空,并創建了大小為4的數組。然后,當此數組太小時,其大小將增加一倍,因此后備數組將像4、8、16、32等那樣增長。每當后備數組增長時,都必須重新分配它,并且必須復制到目前為止存儲的所有元素。與可以立即創建正確大小的數組的第一種情況相比,此操作的成本要高得多。另外,如果您的源集合包含33個元素,則該列表最終將使用64個元素的數組浪費一些內存。
在您的情況下,源集合是一個實現的數組,ICollection<T>
因此,除非源數組很大,否則您不必擔心性能影響。調用ToList()
將只復制源數組并將其包裝在一個List<T>
對象中。即使是第二種情況的性能,也不必為小收藏而擔心。
- 3 回答
- 0 關注
- 1123 瀏覽
添加回答
舉報