2011-11-23 26 views
0

在我的情況下,我有2D ArrayList充滿了繪製水平線,垂直線和填充矩形時使用數據的對象。在不同的情況下,對象的數量是不同的,並且圖像具有不同數量的畫線和矩形。但是圖像有時需要重新繪製。重繪的東西越多,屏幕上的閃光就越強烈(我希望你能弄清楚我的意思是「閃光」)。C#,WinForms繪製存儲在ArrayList中的數據。這是個好主意嗎?

我已經嘗試雙緩衝,但我不認爲我做它的右閃僅改變的類型......但是,這不是當前的情況。

我已閱讀,它很容易從任何地方ArrayList中添加和刪除元素(無論類型),但對它們的訪問是很難的。我還讀到List更好地表現ArrayList(這是否意味着該程序將需要更少的計算機資源?),但是從最後添加和刪除元素只是很容易的。但我不確定Array的性能是否最快。這讓我覺得如果我用Array或List更改ArrayList,閃爍可能變得更弱。

這不會是在我的情況的問題,因爲所有我存儲在ArrayList中的元素構成同一類。

我的問題是:如果我用數組或列表替換ArrayList,我可以削弱閃爍嗎?

回答

1

好的,這裏有兩個問題。 ArrayList vs. List問題對「閃爍」沒有影響,因爲性能差異很小。如果您的列表項目都是相同類型的,或者它們全都來自除object以外的公共基本類型,或者它們全部實現通用接口,那麼List<T>是更好的選擇。這是因爲涉及更少的鑄件甚至拳擊/拆箱。另外,訪問你的物品會更容易。

閃爍:以繪畫事件方法(形式或某種控件)執行所有繪圖。然後調用這種形式或控件的方法Invalidate。不要畫「直接」。作爲一種改進,您可以將矩形結構傳遞給Invalidate,以告知哪些部分必須重繪。在paint方法中,你可以檢查e.ClipRectangle,它告訴你哪個部分必須重繪。這給了你在這裏做一些改進的機會。但是,請注意這一事實,即Windows操作系統本身可以觸發無效,這會導致任意ClipRectangles。

0

要修復「閃爍」,您需要啓用雙緩衝。

你不應該使用ArrayList,因爲它鼓勵錯誤和/或糟糕的設計。
您不應該有包含多種類型的對象的列表。

相反,你應該使用List<T>,或許還有一個多態基類。

1

比較繪圖性能與從ArrayList性能讀取,您不能通過使用另一個數據容器解決閃爍的問題。所以,ArrayList的替代容器不是答案。你需要使用其他一些方法,如;

  • 使用SDLDirectXOpenGL像圖形庫。
  • 繪製到位圖緩衝區並在完成後顯示位圖(類似於雙緩衝,但有時效果會更好)。
  • 繼承一些組件並覆蓋一些方法(如背景繪製)。

還有更多的方法,但你的問題的答案肯定與ArrayList沒有太大的關係。

+0

在某些情況下,對象的數量不只是2×2或4×3,但10×10和更大量...(N×M的有了我的意思是ň陣列,M個元素。)和矩形需要吸引更多的時間。 「減弱閃爍」我並不是指「停止閃爍」,我的意思是如何更快地繪製圖形。是的,我知道我必須在雙緩衝上工作才能解決問題。但如果讓繪圖更快(之後雙緩衝將變得更快),應用程序也將變得更快。這是屬於「必須做」列表的內容之一。 – AlexSavAlexandrov

+0

我總是支持編寫更好的優化代碼,性能改變是否明顯。但在你的情況下,在1000x1000的迭代中,你將獲得大約10-50毫秒。想想畫一個1000000個矩形需要多長時間,而不是10-50毫秒。 (請參閱此處:http://www.dotnetperls.com/unboxing)。這些int類型的結果如此,我認爲它可能需要多達5倍以上的其他類型,並減少迭代100倍。所以,我們都知道繪製1000000個矩形,類似的對象需要花費很長時間。恕我直言,性能增益不會高於%0.1。 –

1

您應該使用List<T>而不是ArrayList,只是爲了擺脫不必要的鑄造的,當你閱讀從列表中的對象。但是,與繪製圖形相比,它的性能收益非常小,不會對您的更新問題產生任何顯着影響。

你可以考慮繪製圖形的位圖,然後繪製位圖,當您需要更新屏幕。


List<T>ArrayList行爲相同的,當涉及到添加和刪除元素;在列表的末尾添加或移除元素很便宜,但在列表的開頭插入或移除元素的成本更高。

數組是列表中最快的,並且List<T>ArrayList都使用數組在內部存儲其元素。但是,您無法調整數組的大小,因此您可能仍然希望使用List<T>,因爲它可以根據需要分配數組,並跟蹤數組的使用量。

+0

'名單'是值類型快得多。 – SLaks

相關問題