2

我需要画大约 1000 条线。这些行每秒更改大约 25 次(因此,每秒 25000 行)。这样做时我可以使用什么来获得可接受的性能?我不喜欢使用 directX 调用,因为该软件还需要在服务器上运行,默认情况下没有 directX。

我尝试了两种不同的方法,但给了我一个融化的 CPU:

Setup1 - 标准 .NET 调用:

  • 双缓冲面板
  • 在内存位图上绘图(使用 Graphics.DrawLine 清除和重绘线条)
  • 使用 Graphics.DrawImageUnscaled 将位图复制到面板
  • profiler 说这两个图形调用是瓶颈

Setup2 - gdi 的 dllimport 调用:

  • 双缓冲面板
  • 使用来自 gdi 的 MoveToEx 和 LineTo 绘制内存位图
  • 使用 BitBlt 将位图复制到面板
  • profiler 说那些非托管调用是瓶颈

如果我使用 WPF 而不是 Winforms,性能会提高吗?或者是通过使用 directX 或第三方库来做到这一点的唯一方法?

干杯

4

3 回答 3

0

调用开销可能是限制因素。在 vanilla GDI 中,有一个PolyPolyline函数,可让您在一次调用中绘制多条线。如果您的所有线都已连接,那么还有一个更简单的折线函数。我认为这些都有 GDI+ 等价物。我会用这些来描述。即使将您的坐标捆绑到这些函数所需的数组中需要一些工作,它也可能比调用单个线条绘图函数的约 1000 次要快。

于 2012-08-25T15:39:05.967 回答
0

我能给出的唯一建议是您似乎可以直接访问硬件,因此请使用标准的双缓冲方法。如果您的硬件支持多线程,或者只是一个内存队列(如准备绘制的位图集合),可能与多线程结合使用,请记住处理器可以在进行一次 IO 操作(屏幕绘制)所需的时间内执行数千次内存操作)。在达到一定的“缓冲区大小”(集合大小)之后,您实际上可以有一个过程来获取数据并转换到内存中的表面(如果需要,可以使用位图)并继续按顺序将它们添加到泛型集合中假设对于接下来的 5 分钟图像,可以对其进行编码以等待面板进程消耗更多的集合。然后在面板 OnPaint 等效项中,它从堆栈底部获取一个内存表面,并将当前的表面与集合底部的一个交换出来。您可以给具有绘图任务的线程更多的处理优先级,因为其他线程自然会更快。请记住用不同的线程锁定内存表面的集合,以便它是线程安全的。祝你好运。

于 2012-09-27T23:45:15.893 回答
0

如果行数固定:

使用 WPF 并将线条添加到画布一次。

每个刻度,根据需要更新行的末端。您也可以更改其他属性。

我会尝试这个,因为它是接近 DirectX 而不直接使用它的最简单方法。

无论如何:在没有像样硬件的服务器上进行这么多图形操作总是会很痛苦。

于 2012-08-25T17:07:55.763 回答