2011-11-23 31 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

相关问题