Complexity of views

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Complexity of views

Chris Uppal-3
A thought.

As the standard tools get more powerful, the Views are inevitably getting
more complex.  I'm starting to notice a sluggishness about opening new CHBs
and SBs.  (This is on a 650Mz machine,)

Thinking about it, I decided to try something that I've been meaning to have
a pop at for a while, and arrange to keep a cached pre-computed View around
for the more complex tools.  When a new browser is opened, it attempts to
use the cached View if there is one rather than unfolding a resource.  It
causes the cache to be refreshed in idle time.

Here's a quick hack at it.  It makes ClassBrowserAbstract class override
#loadResource:inContext:.  It is only a hack (a more polished implementation
might add an LRU cache of Views over a certain size to the ResourceManager)
but it's something to play with.

On my machine it makes quite a difference to the perceived speed of the
UI -- enough that I'll probably keep it installed (and maybe polish it up).

I think the technique could be useful for any complex Shell.  (I remember
that Bill had problems with this in the past, for instance.)

I'm not really convinced that it's appropriate for including in the standard
distribution, but I'm not really convinced that it's not either.  What do
people think, does it make a significant difference to you ?

    -- chris

===========================
!ClassBrowserAbstract class methodsFor!

loadViewResource: aString inContext: aParentView
 "Private - Load a view resource called aString owned by this class.
 Overridden to maintain a pre-deSTBed View to allow faster opening"

 | rc |
#CUadded.

 aString = self defaultView ifFalse: [^ super loadViewResource: aString
inContext: aParentView].

 rc := self propertyAt: #ResourceCache ifAbsent: [nil].
 self removePropertyAt: #ResourceCache ifAbsent: [].

 rc := rc ifNil: [super loadViewResource: aString inContext: aParentView].

 SessionManager inputState queueDeferredAction:
   [self propertyAt: #ResourceCache put: (super loadViewResource: aString
inContext: aParentView)].

 ^ rc.! !
!ClassBrowserAbstract class categoriesFor:
#loadViewResource:inContext:!operations!private! !

!ClassBrowserAbstract class methodsFor!

defaultView: aString
 "Set the default view name.
 Overriden to clear the resource cache"
#CUadded.

 self removePropertyAt: #ResourceCache ifAbsent: [].

 ^ super defaultView: aString.! !
!ClassBrowserAbstract class categoriesFor: #defaultView:!accessing!public! !
===========================


Reply | Threaded
Open this post in threaded view
|

Re: Complexity of views

Steve Alan Waring
Hi Chris,

>  does it make a significant difference to you ?

Nice! ... big difference on my 500Mhz machine, the browsers snap open!

Steve


Reply | Threaded
Open this post in threaded view
|

Re: Complexity of views

Bill Schwab
In reply to this post by Chris Uppal-3
Chris,

> I think the technique could be useful for any complex Shell.  (I remember
> that Bill had problems with this in the past, for instance.)

Yes, though it's end user apps that I care about.  Interestingly, it's
taking longer than ever for my CHBs to open, and I'm enjoying it because
they are filtered - well worth the wait.

It's surprisingly easy to slap 100 or more widgets on the screen at one
time, and Windows controls don't do very well in large numbers.  Add to that
some binary filing overhead and you get multi-second delays to open a new
view :(    I've solved (sorta) the problem mostly by emulating the controls
that I use in large numbers.

The one down side I see to caching views is that it adds to the demands on
resources, which could result in more unexplained crashes on 9x machines.
OTOH, it would make the app more responsive so it would suffer less frantic
pounding when it's too busy to respond - something I've long suspected is a
factor in many 9x disasters.


> Here's a quick hack at it.  It makes ClassBrowserAbstract class override
> #loadResource:inContext:.  It is only a hack (a more polished
implementation
> might add an LRU cache of Views over a certain size to the
ResourceManager)
> but it's something to play with.

Something like this would make a nice addition to the base system provided
it could be configured away if it's not wanted.  Rather than caching "large
views", you might allow resource identifiers to be registered for caching.
I have some big views that get created only once at app startup, so caching
won't help the end user.  In fact, loading up another would only waste
memory (and worse yet on 9x, resources).  My users probably would benefit
from caching frequently-used (dialog) views, and I would want to tweak the
space/speed tradeoff carefully, and maybe even tailor it to the individual
user.

Another thing we might consider is having some views marked for recycling
rather than destruction.  Most of my repeatable 9x crashes that have emerged
over time turned out to be caused by resource starvation, and careful
control over the life cycles of GDI objects fixed them.  By better control,
I mean freeing them "now" vs. waiting for finalization, and better yet using
stock objects that don't need to be freed.

Note that some views might be difficult to recycle because of side effects
from a previous life.  Presenters might be able to help given a
#onPrepareForRecycle: (probably with the view resource name as an argument
just in case) that would be sent only if the view resource were marked for
recycling.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]