Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to improve the performance of GDI programming

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will give you a detailed explanation on how to improve the performance of GDI programming. The editor thinks it is very practical, so I share it with you for reference. I hope you can get something after reading this article.

IntPtrhandle=font.ToHfont (); / / performance bottleneck / / … SafeNativeMethods.DeleteObject (handle)

Because when the control uses GDI to draw words, it gets the Handle of Font by calling the Font.ToHfont () method. And this method is very slow. And the control is called when drawing each Item, and there are many such controls in Form, so the number of calls is considerable. This creates this performance bottleneck.

Because the operating system does not allow GDI to have more than 9999 Handle. If there are more than 9999, the program will collapse. Therefore, we must not make the number of Handle of GDI in the program increase linearly with some factors. All, generally create Handle when using GDI to draw words, and then delete it after using it. This also prevents GDI leakage.

Considering that most of the time, the Font is the same, if you can cache the Handle created by Font, the performance will be greatly improved. However, if the cached Handle is not deleted in time, if there are too many different Font, there is a chance to reach the number allowed by the operating system, thus causing the program to crash.

Here are my solutions to improve GDI programming performance:

1. Use the SafeFontHandle class to prevent GDI leakage. SafeFontHandle is derived from SafeHandleZeroOrMinusOneIsInvalid and SafeHandleZeroOrMinusOneIsInvalid is derived from CriticalFinalizerObject. GC does special treatment to CriticalFinalizerObject to ensure that all critical termination code has the opportunity to execute.

Code # regionTheSafeFontHandleclass internalsealedclassSafeFontHandle:SafeHandleZeroOrMinusOneIsInvalid {privateSafeFontHandle (): base (true) {} publicSafeFontHandle (IntPtrpreexistingHandle,boolownsHandle): base (ownsHandle) {base.SetHandle (preexistingHandle);} protectedoverrideboolReleaseHandle () {returnSafeNativeMethods.DeleteNativeFontHandle (base.handle);}} # endregion

2. Use the HandleCollector class to prevent the Handle of Font from exceeding the operating system * limit. HandleCollector tracks the Handle of the Font and enforces garbage collection when it reaches the specified threshold. After garbage collection, SafeFontHandle releases Font's handle.

Code [SuppressUnmanagedCodeSecurity] internalstaticclassSafeNativeMethods {privatestaticHandleCollectorFontHandleCollector=newHandleCollector ("GdiFontHandle", 500jue 1000); internalstaticIntPtrCreateNativeFontHandle (Fontfont) {IntPtrhandle=font.ToHfont (); if (handleworthy IntPtr.Zero) {FontHandleCollector.Add ();} returnhandle;} internalstaticboolDeleteNativeFontHandle (IntPtrhandle) {boolsuccess=DeleteObject (handle); if (success) {FontHandleCollector.Remove ();} returnsuccess;} [System.Runtime.InteropServices.DllImportAttribute ("gdi32.dll")] internalstaticexternboolDeleteObject (System.IntPtrgdiObject);}

3. Use the weak reference cache class WeakReferenceCachePool to cache SafeFontHandle, which does not affect the normal garbage collection of SafeFontHandle by GC, thus releasing the Handle of Font. For the weak reference cache class WeakReferenceCachePool, you can refer to the article "A weak reference cache class".

Code internalstaticclassSafeFontHandleFactory {# regionInstanceData privatestaticWeakReferenceCachePool_cachePool=newWeakReferenceCachePool (); # endregion # regionMethods publicstaticSafeFontHandleCreateSafeFontHandle (Fontfont) {if (font==null) {thrownewArgumentNullException ();} SafeFontHandlesafeFontHandle=_ cachePool; if (safeFontHandle==null) {IntPtrnativeHandle=SafeNativeMethods.CreateNativeFontHandle (font); safeFontHandle=newSafeFontHandle (nativeHandle,true); _ cachePool = safeFontHandle;} returnsafeFontHandle;} # endregion}

In this way, the Handle of GDI is successfully cached, and the Handle of GDI will not grow linearly after use. Whenever GC recovery occurs, the Handle of GDI will be cleared, or when the total number reaches the threshold specified by HandleCollector, it will also be cleared. The GC garbage collection mechanism is used to automatically balance performance and memory footprint.

Here is the test code. The tests to improve the programming performance of GDI are as follows:

Do not use weak reference caching

TimeElapsed:350ms

CPUCycles:952061115

Gen0:1

Gen1:0

Gen2:0

GDIincrement:0

Improve GDI programming performance by using weak reference caching

TimeElapsed:42ms

CPUCycles:142020499

Gen0:0

Gen1:0

Gen2:0

GDIincrement:0

This is the end of this article on "how to improve GDI programming performance". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it out for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report