
Signature
Regards,
Lloyd Dupont
NovaMind development team
NovaMind Software
Mind Mapping Software
<www.nova-mind.com>
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)
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)
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)