【问题标题】:.NET GDI+ drawing performance.NET GDI+ 绘图性能
【发布时间】:2012-08-20 19:00:09
【问题描述】:

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

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

Setup1 - 标准 .NET 调用:

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

Setup2 - gdi 的 dllimport 调用:

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

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

干杯

【问题讨论】:

  • 线条的尺寸是多少?
  • 它们的长度可变,介于 1 到 500 像素之间。
  • 行数是固定的吗?

标签: .net drawing gdi


【解决方案1】:

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

【讨论】:

  • 我认为Graphics.DrawLines 是等价的。还有其他批处理风格的绘图调用:Graphics.DrawBieziersGraphics.DrawRectangesGraphics.FillRectanges
  • @BasiK:使用PolyPolyline,你可以画出许多不连贯的线。
  • 感谢您的信息。虽然 PolyPolyline 调用的时间似乎稍好一些,但用户体验没有明显差异。
  • @BasiK:你能提供一些更具体的时间信息吗?你确定瓶颈是画线吗?
【解决方案2】:

在固定行数的情况下:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2020-02-16
      • 1970-01-01
      相关资源
      最近更新 更多