GDI +性能技巧 [英] GDI+ performance tricks

查看:101
本文介绍了GDI +性能技巧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道关于GDI +性能的可靠(而且希望是广泛的)书籍/网站吗?

Does anyone know of any reliable (and, hopefully, extensive) books/websites that discuss GDI+ performance (beyond the obvious)?

例如,我最近遇到了这项出色的实验.我最近还注意到,Graphics.FillPath()是方法,比Graphics.DrawPath()快得多.我很想知道我还缺少其他哪些重要信息.

For example, I recently came across this excellent experiment. I also recently noticed that Graphics.FillPath() is way, way faster than Graphics.DrawPath(). I'd love to know what other vital bits of information I'm missing.

商誉, 大卫

推荐答案

嗯.如果您需要绘制路径的轮廓,那么知道FillPath比DrawPath快是没有好处的!

Hmmm. There is no gain in knowing that FillPath is faster than DrawPath if you need to draw the path's outline!

优化GDI +的最佳方法与任何其他代码完全相同:首先,不要对其进行优化.相反:

The best way to optimise GDI+ is exactly the same as for any other code: Firstly, don't optimise it. Instead:

  • 首先编写它,使其简单地起作用,然后确定它实际上是否太慢.
  • 然后检查您的算法":
    • 简化您的绘图(减少绘图的数量),它会更快(并且在大多数情况下,看起来会更好,减少了混乱).
    • 您是在每次绘制整个显示器吗?还是在使用剪辑矩形来避免绘制不需要更新的图像部分?
    • 检查画画的方式.您是否在为每次重绘创建和销毁资源(例如画笔和钢笔)?将它们缓存在成员变量中.您是否多次重画同一像素? (例如,绘制背景,然后在顶部绘制位图,然后在顶部绘制矩形-也许可以避免其中的一些重绘).仅用10个线段看起来就够好时,您是否使用100个多边形线段绘制曲线?窗口滚动时,是否让操作系统移动现有图像,所以您只需要重新绘制新暴露的条带,还是浪费时间重新绘制整个窗口?
    • 您正在使用变换还是在代码中进行冗长的定位计算?
    • 检查任何循环,并确保从其中移出尽可能多的代码-预先计算在循环中使用的值,等等.确保循环尽可能以对cpu缓存友好的方向/方式对数据进行迭代.
    • 重绘过程中您正在处理的数据中是否有任何内容?也许其中一些可以预先计算或以更适合渲染的形式组织.例如不同类型的列表会更快地枚举您的数据吗?您是否正在处理1000个数据项以查找需要绘制的10个数据项?
    • 您可以使用其他方法获得相同的外观吗?例如您可以通过以黑白交替绘制64个正方形来绘制棋盘.绘制32个黑色然后绘制32个白色正方形可能会更快,因此可以避免在rect之间改变状态.但是实际上,您可以使用白色背景透明,4个黑色矩形和4个XOR矩形(8个矩形而不是64个=>更快的算法)来绘制它.
    • Start by writing it so it simply works, and then decide if it is actually too slow.
    • Then examine your "algorithm":
      • Simplify what you are drawing (reduce the number of things you are drawing) and it will go faster (and in most cases will look better for having reduced the clutter).
      • Are you drawing your entire display every time, or are you using the clip rectangle to avoid drawing parts of the image that don't need to be updated?
      • Examine how you draw things. Are you creating and destroying resources (e.g. brushes and pens) for every redraw? Cache them in a member variable. Are you over-drawing the same pixel multiple times? (e.g. drawing the background then drawing a bitmap on top then drawing a rectangle on top of that - perhaps you can avoid some of these redraws). Are you drawing a curve using 100 polygon segments when it looks good enough with only 10 segments? When the window scrolls, do you get the OS to move the existing image so you only need to redraw the newly exposed strip, or do you waste time redrawing the entire window?
      • Are you using transforms or are you doing lengthy positioning calculations in your code?
      • Check any loops and make sure you move as much code out of them as possible - precalculate values you use within the loop, etc. Make sure your loops iterate over your data in a cpu-cache-friendly direction/manner where possible.
      • Is there anything in your data that you are processing during the redraw? Perhaps some of this can be precalculated or organised in a more rendering-optimal form. e.g. Would a different type of list be faster to enumerate your data from? Are you processing 1000 data items to find the 10 you need to draw?
      • Can you achieve the same look with a different approach? e.g. You can draw a chess board by drawing 64 squares in alternating black and white. It might be faster to draw 32 black and then 32 white squares so you avoid state changes between the rects. But you can actually draw it using a white background clear, 4 black rectangles, and 4 XOR rectangles (8 rects instead of 64 => much faster algorithm).

      完成所有这些操作后,您就可以开始寻找有关优化渲染的书籍.如果仍然太慢,当然可以.运行探查器,找出渲染中最慢的部分.

      Once you have done all these things you can start looking for books about optimising the rendering. If it is still too slow, of course. Run a profiler to find out which parts of the rendering are the slowest.

      在您认为可能会有所收获的地方,请尝试不同的渲染方式(例如,Graphics.Clear()可能比FillRectangle()填充背景要快得多)或不同的渲染顺序(绘制首先要用一种颜色处理所有事情,以防状态更改花费您的时间-批处理操作在现代图形卡中通常非常重要,一次绘制多个多边形的调用通常比进行多次单个多边形调用要快,因此您可以累加全部您的多边形放入延迟渲染缓冲区中,然后在渲染过程结束时将其全部提交?)

      Where you think you might be able to make gains, try different ways of rendering things (e.g. it's likely that Graphics.Clear() will be much faster than filling the background with FillRectangle()), or different rendering orders (draw all the things of one colour first, in case state changes cost you time - batching operations is often very important with modern graphics cards. A single call that draws multiple polygons is usually faster than making multiple single-polygon calls, so can you accumulate all your polys into a deferred-rendering buffer and then commit them all at the end of your rendering pass?)

      在那之后,您可能不得不考虑使用GDI或DirectX来更接近硬件.

      After that, you may have to look at using GDI or DirectX to get closer to the hardware.

      这篇关于GDI +性能技巧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆