Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Drawing / June 2006

Tip: Looking for answers? Try searching our database.

Performance & new Pen() / new Brush()

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Lloyd Dupont - 15 Jun 2006 07:23 GMT
In my drawing code I recusrively create an average number of pens and
brushes of, let's guess: 300?
Would I see performance improvment by just caching those?

(actually I use and create all of them in a using() statment)

Signature

Regards,
Lloyd Dupont

NovaMind development team
NovaMind Software
Mind Mapping Software
<www.nova-mind.com>

Göran Andersson - 15 Jun 2006 09:04 GMT
Try to reuse them if you can. Those .NET classes are wrappers around the
corresponding GDI objects, so they use GDI resources as well.

> In my drawing code I recusrively create an average number of pens and
> brushes of, let's guess: 300?
> Would I see performance improvment by just caching those?
>
> (actually I use and create all of them in a using() statment)
Lloyd Dupont - 15 Jun 2006 10:53 GMT
I will try but I wonder if it's worth the effort.
I have to rewrite a lot of code and if it's to achieve 1% perfromance
improvment, it's not really worth it....

> Try to reuse them if you can. Those .NET classes are wrappers around the
> corresponding GDI objects, so they use GDI resources as well.
[quoted text clipped - 4 lines]
>>
>> (actually I use and create all of them in a using() statment)
Göran Andersson - 15 Jun 2006 11:40 GMT
Yes, if the code gets much more complicated, it's hardly worth it. There
is a value in keeping the code as simple as possible also.

Most optimization can be saved until you run into performance problems.

> I will try but I wonder if it's worth the effort.
> I have to rewrite a lot of code and if it's to achieve 1% perfromance
[quoted text clipped - 8 lines]
>>>
>>> (actually I use and create all of them in a using() statment)
Jay B. Harlow [MVP - Outlook] - 15 Jun 2006 13:09 GMT
Lloyd,
Do the pens & brushes tend to be the same color?

Creating 300 red brushes seems wasteful.

Generally what I do is define a "Palette" object that contains the distinct
Pens & Brushes that my drawing code needs, I create & dispose this "Palette"
object in the OnPaint event. The "Palette" object is responsible for
disposing of the contained.

Something like:

   Public Class Palette
       Implements IDisposable

       Private ReadOnly m_background As Brush
       Private ReadOnly m_border As Pen

       Public Sub New()
           m_background = New SolidBrush(Color.Red)
           m_border = New Pen(Color.Blue)
       End Sub

       Public ReadOnly Property Background() As Brush
           Get
               Return m_background
           End Get
       End Property

       Public ReadOnly Property Border() As Pen
           Get
               Return m_border
           End Get
       End Property

       Public Sub Dispose() Implements IDisposable.Dispose
           m_background.Dispose()
           m_border.Dispose()
       End Sub

   End Class

   Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
       MyBase.OnPaint(e)
       Using palette As New Palette
           e.Graphics.FillRectangle(palette.Background, ClientRectangle)
           e.Graphics.DrawRectangle(palette.Border, ClientRectangle)
       End Using
   End Sub

Note, sometimes I refactor my code so the Palette object does the drawing,
in which case I rename the Palette to Renderer.

   Public Class Renderer
       Inherits Palette

       Public Sub DrawBorder(ByVal gr As Graphics, ByVal rect As Rectangle)
           gr.DrawRectangle(Border, rect)
       End Sub

   End Class

   Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
       MyBase.OnPaint(e)
       Using renderer As New Renderer
           e.Graphics.FillRectangle(palette.Background, ClientRectangle)
           palette.DrawBorder(e.Graphics, ClientRectangle)
       End Using
   End Sub

NOTE: I don't do the above for performance as simple organization & to
reduce "code smells". Although I have never timed it I would expect some
performance improvements as its reducing the number of objects created,
which should reduce the amount of GC pressure.

Signature

Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net

| In my drawing code I recusrively create an average number of pens and
| brushes of, let's guess: 300?
| Would I see performance improvment by just caching those?
|
| (actually I use and create all of them in a using() statment)
Jay B. Harlow [MVP - Outlook] - 15 Jun 2006 13:20 GMT
Lloyd,
Doh! I should add.

Introducing the Renderer actually allows you to change the drawing process
itself, without changing the "Process" (the recursion).

Take for example the ToolStripRenderer in .NET 2.0:

http://msdn2.microsoft.com/en-us/library/ms229720.aspx

The framework ships with a Professional & a System Renderer that changes how
a tool strip is drawn. By changing the ToolStrip.Renderer property you
change how the toolstrip is drawn.

Signature

Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net

| Lloyd,
| Do the pens & brushes tend to be the same color?
[quoted text clipped - 76 lines]
||
|| (actually I use and create all of them in a using() statment)
Lloyd Dupont - 15 Jun 2006 15:42 GMT
I was thinking to do something like that!
I was just wondering if it was worth going through all my "new Pen" and "new
Brush" and change them....

> Lloyd,
> Do the pens & brushes tend to be the same color?
[quoted text clipped - 79 lines]
> |
> | (actually I use and create all of them in a using() statment)
Jay B. Harlow [MVP - Outlook] - 15 Jun 2006 23:53 GMT
Lloyd,
From a maintenance & possibly reduce code duplication point of view, yes I
believe it is worth it.

From an empirical performance point of view, you would need to profile it to
see which is faster.

When considering performance consider the 80/20 rule. That is 80% of the
execution of your program is spent in 20% of the code. Again profiling would
identify if this code is part of the 80% or the 20%. (it would help identify
the performance benefit). Remember the performance benefit is more then
simple execution time. I also consider GC pressure when reviewing
performance... The code itself may be really fast, however the number of
objects created may be causing the GC to work harder then it should, or be
causing your working set to increase faster & higher then it needs to...

However I think the real pay off will be better organized & stream lined
code. Making further development easier & more flexible...

Signature

Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net

|I was thinking to do something like that!
| I was just wondering if it was worth going through all my "new Pen" and "new
[quoted text clipped - 83 lines]
| > |
| > | (actually I use and create all of them in a using() statment)
Lloyd Dupont - 19 Jun 2006 13:43 GMT
The profiling didn't work :-(
I posted a bug report to redgate, my app die almost instantly anytime it's
started with ANTS :-(
However it did bring 1 good lead.

Also an old fashion measurement seems to reveal that new Pen() / new Brush()
operation add something around a 0.4 ms. ovehead....

So I did 2 optimisation (including Pens & Brushes caching, and the one tip
from ANT) and it's already much faster!

Now it would be nice if ANTS will work let me profile my whole application!

> Lloyd,
> From a maintenance & possibly reduce code duplication point of view, yes I
[quoted text clipped - 112 lines]
> | > |
> | > | (actually I use and create all of them in a using() statment)
James Westgate - 16 Jun 2006 10:31 GMT
We tend to use a singleton and cache pens and brushes that are
frequently used there. Havent seen any problems.
There should also be some predefined system pens and brushes you can use.

James

http://www.crainiate.net

> In my drawing code I recusrively create an average number of pens and
> brushes of, let's guess: 300?
> Would I see performance improvment by just caching those?
>
> (actually I use and create all of them in a using() statment)

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.