我目前使用List<T>
作爲隊列(使用lst[0]
,然後lst.removeAt(0)
)來保存對象。在給定的時間內最多約20個項目。我意識到有一個實際的Queue<T>
類。我想知道是否有任何好處(性能,內存等)使用Queue<T>
而不是List<T>
充當隊列?隊列<T> vs列表<T>
回答
性能可以分析。雖然在這種情況下,你可能需要運行代碼數百萬次才能真正獲得有價值的差異。
我會這樣說:Queue<T>
會暴露你的意圖更明確的人都知道隊列是如何工作的。
像隊列一樣使用的列表不是很清楚,特別是如果你有很多不必要的索引和RemoveAt(magicNumber)
代碼。從代碼維護的角度來看,Dequeue
是更多的消費品。
如果這會給您帶來可衡量的性能問題,您可以解決它。不要每個潛在的性能問題提前。
爲什麼我們不應該預先解決所有潛在的性能問題? –
@JohnIsaiahCarmona:因爲在10個元素上使用O(n^2)算法而不是O(n)算法不是性能問題。 – Jon
@JohnIsaiahCarmona因爲當你不需要它時,你陷入了微觀優化的陷阱。我對這一切的看法是我們應該留意明顯的夾擊者,但是A和B之間的幾個毫秒不值得擔心,直到他們成爲問題。在大多數情況下,可維護的可讀代碼比性能更重要。 –
除了Queue<T>
類實現隊列和List<T>
類實現列表這一事實之外,還存在性能差異。
每當您從List<T>
中刪除第一個元素時,都會複製隊列中的所有元素。隊列中只有20個元素可能不明顯。但是,當您從Queue<T>
中取出下一個元素時,不會發生這樣的複製,並且總是會更快。如果隊列很長,則差異可能很大。
我想強調HugoRune已經指出的內容。隊列比列表快得多,在這個用例中,列表的內存訪問是1對n。我有一個類似的用例,但我有數百個值,我將使用Queue,因爲它的速度快了一個數量級。
有關隊列正在List上實現的說明:關鍵是「已實施」。它不會在出隊時將每個值複製到新的內存位置,而不是使用循環緩衝區。這可以在「列表頂部」完成,而不會受到直接使用List意味着的副本的處罰。
除非容量是固定大小,否則不能使用循環緩衝區。 – Didaxis
簡短的回答:當它的使用就像一個隊列
Queue<T>
比List<T>
更快。當像列表一樣使用時,List<T>
比Queue<T>
更快。
龍答案:
甲Queue<T>
爲出隊操作,這是一個O(1)的操作速度更快。整個數組的後續項目塊不會向上移動。這是可能的,因爲Queue<T>
不需要從隨機位置移除,而僅從頂部移除。所以它保持一個頭(物品被拉到Dequeue
)和尾部位置(物品被添加到Enqueue
)。另一方面,從List<T>
的頂部移除需要自己將每個後續項目的位置移動一個。這是O(n) - 最壞的情況是,如果你從頂層移除,這是一個出隊操作。如果您在循環中出隊,速度優勢可以引人注目。
一個List<T>
是更好的性能,如果你需要索引訪問,隨機檢索等。Queue<T>
將不得不枚舉完全找到合適的索引位置(它不公開IList<T>
)。
也就是說,Stack<T>
與List<T>
距離更近,在推動和彈出操作中沒有性能差異。它們都推動結束並從數組結構中移除(兩者都是O(1))。
當然,你應該使用正確的結構,揭示了意向。在大多數情況下,它們的表現會更好,因爲它們是爲此目的而量身定製的。我相信根本沒有任何性能差異,微軟不會僅僅在框架中包含Queue<T>
和Stack<T>
僅僅是不同的語義。如果是這樣的話,它本來就容易擴展。考慮SortedDictionary<K, V>
和SortedList<K, V>
,兩者都完全相同,但僅通過性能特徵進行區分;他們在BCL中找到了一席之地。
在加重情況下怎麼樣? –
@AlexanderRyanBaggett它應該沒有什麼區別(我最好的猜測),但你應該真的使用更好地揭示意圖的結構。他們都向開發者講述了不同的故事。 – nawfal
- 1. 部隊更新TGT
- 2. 隊列列表<T>
- 3. 操作<<在隊列
- 4. 無法從AD獲得TGT
- 5. 鏈表VS列表<T>
- 6. 不能設置爲空的特性「TGT」
- 7. GSSManager.createCredential如何獲取Kerberos密鑰和TGT?
- 8. 使用服務負責人獲得TGT
- 9. 由TGT創建iSCSI目標不能
- 10. 隊列<byte>與流
- 11. 隊列<string&>錯誤
- 12. 列表<Object>和列表<?>
- 13. 的ArrayList VS列表<object>
- 14. 實體類String [] vs列表<String>
- 15. 列表<string>列出<DateTime>
- 16. 列表<double[][]>列出<double[]>
- 17. 列表<Product>。加入(列表<Order>,...)與列表<Order>。加入(列表<Product>,...)?
- 18. 如何投票列表<<MyClass>至列表<T>?
- 19. 何時使用收集<T> VS列表<T>
- 20. 列表<?> vs List <?擴展對象>
- 21. @OneToMany列表<> VS集<>差異
- 22. 序列表列表<T>包含列表<T>
- 23. 儘管allowtgtsessionkey註冊表項無法檢索TGT
- 24. 更改通用隊列隊列<T>類到非通用隊列類
- 25. NHibernate Session.Query <>列列表?
- 26. 迭代隊列<T>保證按隊列順序?
- 27. 如何將隊列<int, int>插入隊列?
- 28. 將T陣列併發隊列排隊<T>
- 29. 如何在C#中將隊列添加到隊列<T>?
- 30. 從列表<>
'也許'不是如果你不使用超過20個項目。但是你可以使用StopWatch類來測量它。 – alexn
這取決於您的使用情況,如果它確實很重要。 lst.RemoveAt(0)將導致列表重定位所有元素,而隊列更智能。理論上Queue更好,但要確保你應該測量你的用例。 –
您不能按索引訪問隊列。 你必須使用你出列的條目,而你不能將它們放回去。 Peek不是一個解決方案,但Count> 0可能是。 – Jay