Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want raw speed, the best option is to use DirectX. The next best is probably to use GDI from C++ and provide a managed interface to call it. Then probably to p/invoke to GDI directly from C#, and last to use GDI+ in C#. But depending on what you're doing you may not see a huge difference. Multithreading may not help you if you're limited by the speed at which the graphics card can be driven by GDI+, but could be beneficial if you're processor bound while working out "what to draw". If you're printing many images in sequence, you may gain by running precalculation, rendering, and printing "phases" on separate threads.</p> <p>However, there are a number of things you can do to optimise redraw speed, both optimisations and compromises, and these approaches will apply to any rendering system you choose. Indeed, most of these stem from the same principles used when optimising code.</p> <p>How can you minimise the amount that you draw?</p> <p>Firstly, eliminate unnecessary work. Think about each element you are drawing - is it really necessary? Often a simpler design can actually look better while saving a lot of rendering effort. Consider whether a grad fill can be replaced by a flat fill, or whether a rounded rectangle will look acceptable as a plain rectangle (and test whether doing this even provides any speed benefit on your hardware before throwing it away!)</p> <p>Challenge your assumptions - e.g. the "high resolution" requirement - often if you're printing on something like a dye-sub printer (which is a process that introduces a bit of colour bleed) or a CMYK printer that uses any form of dithering to mix colours (which has a much lower practical resolution than the dot pitch the printer can resolve), a relatively low resolution anti-aliased image can often produce just as good a result as a super-high-res one. If you're outputting to a 2400dpi black and white printer, you may still find that 1200dpi or even 600dpi is acceptable (you get ever decreasing returns as you increase the resolution, and most people won't notice the difference between 600dpi and 2400dpi). Just print some typical examples out using different source resolutions to see what the results are like. If you can halve the resolution you could potentially render as much as 4x faster.</p> <p>Generally try to avoid overdrawing the same area - If you want to draw a black frame around a region, you could draw a white rectangle inside a black rectangle, but this means filling all the pixels in the middle twice. You may improve the performance by drawing 4 black rectangles around the outside to draw the frame exactly. Conversely, if you have a lot of drawing primitives, can you reduce the number of primitives you're drawing? e.g. If you are drawing a lot of stripes, you can draw alternating rectangles of different colours (= 2n rectangles), or you can fill the entire background with one colour and then only draw the rectangles for the second colour (= n+1 rectangles). Reducing the number of individual calls to GDI+ methods can often provide significant gains, especially if you have fast graphics hardware.</p> <p>If you draw any portion of the image more than once, consider caching it (render it into a bitmap and then blitting it to your final image when needed). The more complex this sub-image is, the more likely it is that caching it will pay off. For example, if you have a repeating pattern like a ruler, don't draw every ruler marking as a separate line - render a repeating section of the ruler (e.g. 10 lines or 50) and then blit this prerendered only a few times to draw the final ruler.</p> <p>Similarly, avoid doing lots of unnecessary work (like many MeasureString calls for values that could be precalculated once or even approximated. Or if you're stepping through a lot of Y values, try to do it by adding an offset on each iteration rather than recaclualting the absolute position using mutliples every time).</p> <p>Try to "batch" drawing to minimise the number of state changes and/or drawing method calls that are necessary - e.g. draw all the elements that are in one colour/texture/brush before you move on to the next colour. Use "batch" rendering calls (e.g. Draw a polyline primitive once rather than calling DrawLine 100 times).</p> <p>If you're doing any per-pixel operations, then it's usually a lot faster to grab the raw image buffer and manipulate it directly than to call GetPixel/SetPixel methods.</p> <p>And as you've already mentioned, you can turn off expensive operations such as anti-aliasing and font smoothing that won't be of any/much benefit in your specific case.</p> <p>And of course, look at the code you're rendering with - profile it and apply the usual optimisations to help it flow efficiently.</p> <p>Lastly, there comes a point where you should consider whether a hardware upgrade might be a cheap and effective solution - if you have a slow PC and a low end graphics card there may be a significant gain to be had by just buying a new PC with a better graphics card in it. Or if the images are huge, you may find a couple of GB more RAM eliminates virtual memory paging overheads. It may sound expensive, but there comes a point where the cost/benefit of new hardware is better than ploughing more money into additional work on optimisations (and their ever decreasing returns).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload