[AccessD] Framework Discussion - Class performance

John W. Colby jwcolby at colbyconsulting.com
Tue Mar 16 12:34:47 CST 2004


I have had a lot of people worry, if you will, about loading hundreds of
instances of various classes.  What does this do in terms of memory?  How
does Access (VBA) handle the loading of this stuff?  If I have a thousand
lines of code in a text box class and load 100 text box classes, do I have
100,000 lines of code loads?  What about variables?  If a class loads, when
the second instance loads is it using the same variables?  What about static
variables in procedures?

In order to answer the "performance" issue perhaps it would be useful to
talk about how classes do what they do.

We are told, and I have no way to test it myself to find out, but we are
told, that in a library an entire module loads at once.  If you call a
function in a library, every function in that module is loaded into memory.
There is a lot of discussion about breaking modules down into tightly
related functions so that we aren't loading a lot of code that isn't needed
because we call only one function.

I have already discussed my take on the matter, if I load the whole darned
thing, my 5mbytes will be small potatoes to the footprint of my application,
Access, Outlook, Word and Windows.  But if you truly need something to worry
about, you are of course welcomed to break your modules down into tiny
little things so that only the exact functions you need get loaded.

As for classes, by definition since I am loading a piece of that class, the
whole banana is going to load.  After that however when the second instance
loads no more CODE loads, just like a second instance of any method in a
regular module doesn't load over and over.

When a function loads, a STACK is created onto which the arguments being
passed in are placed.  Also placed into that stack are the variables
internal to the function, WITH THE EXCEPTION OF static variables.  Static
variables are placed on the HEAP which is a global area of memory allocated
to the application by Windows.  Variables declared in the header of ANY
MODULE, class or otherwise are placed on the heap.  What this means is that,
for example, my class has a single Long Integer declared in the class
header.  As the class loads, ALL OF THE CODE loads, then memory is allocated
by Access (VBA Actually) for that Long Integer on the heap.  When I load a
second instance of the class, I add exactly and ONLY one more Long Integer
to the heap.  No more code is loaded.  Of course this isn't exactly true
since in order to load that instance I have to declare a variable somewhere
to hold a pointer to the class itself, but the concept remains that only the
pointer to the class and the data in the header of the second instance of
the class is actually "overhead" of that instance.

So if I load a dclsFrm, all the code loads and all of the variables for that
form.  Load a second form and only the data for that second dclsFrm instance
loads.  Load 45 dclsCtlCbo instances and all of the code in dclsCtlCbo loads
plus any variables in the header, after which 44 "headers" are loaded (the
variables for 44 other instances).

As you can see, once you load one, the overhead for the next 10 or 1000 is
negligible - at least in terms of additional code and heap space.

There may or may not be other "overhead" such as recordsets opened and data
loaded into collections etc.  That is indeed an issue, it is very real
overhead, and it can't be discounted.  We as class designers need to be
aware of how this stuff works, what is and isn't loaded for each instance of
any given class, and how that might influence performance.  I do a lot of
stuff with collections.  I load a SysVar class which loads off of disk
dozens of SysVars into collections.  Yes, that is real overhead for that
class, and I can calculate roughly how much memory is used and how long it
takes to get the data off the disk and into the collection.  Having done
that however, it sits there in memory until the application closes.  My app
runs faster because I used a few thousand bytes of memory to just load the
SysVars instead of getting them off the disk every time I want to know the
value of the SysVar.

I do not intend to make light of the overhead of class programming.  If you
are attempting to squeeze this stuff into a Win98 box with 32 megs of
memory, a framework probably isn't the way to proceed.  On the other hand if
you are developing an app for a small company with 5 computers, the
development time a Framework can save you, and the difference in your bill
to the client, just might buy the client all new hardware.  Which would the
client prefer?  New 2ghz machines costing $1,000 apiece or a bill of an
additional $5000 for your time?

Frameworks can save a LOT of programming effort in many cases.  There are
those out there who have never tried them, can't really get a handle on how
they work, and will just dismiss them as "can't possibly help me".  There
are others who have already built their own and know what I am talking
about.  And yes, there may be one or two who truly don't do things that a
framework would be useful for.

I can't say I've ever met anyone ...  ;-)

John W. Colby
www.ColbyConsulting.com





More information about the AccessD mailing list