home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!newsgate.watson.ibm.com!yktnews!admin!wo0z!lwloen
- From: lwloen@rchland.vnet.ibm.com (Larry Loen)
- Subject: Small objs & When/whether to overload "new" with statics
- Sender: news@rchland.ibm.com
- Message-ID: <1993Jan04.162941.13841@rchland.ibm.com>
- Date: Mon, 04 Jan 1993 16:29:41 GMT
- Reply-To: lwloen@rchland.vnet.ibm.com
- Disclaimer: This posting represents the poster's views, not necessarily those of IBM
- Nntp-Posting-Host: wo0z.rchland.ibm.com
- Organization: IBM Rochester
- Lines: 103
-
- Suppose I have a small "helper" class object like this:
-
- class BitRef { // handles assign of bits within char (actually, bit) arrays
- int loc; // bit location (offset) 0 origin, 0 h.o.bit
- char* data; // pointer to some character (actually bit) array
- static char cvt[9];
- static char cvtn[9];
- // cvt[] = { 128,64,32,16,8,4,2,1 }; elsewhere
- // cvtn[]= { 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE }
- int GetBit() const { // return bit at current loc
- int i,j; char k;
- i=loc/8; j=(loc&7);
- k= (data[i]& cvt[j]);
- if (k!=0) return 1; else return 0;
- }; // end GetBit()
- public:
- BitRef(int l,char *d) : loc(l),data(d) {};
- BitRef& operator = (int q)
- { int i,j; char k;
- i=loc/8; j=(loc&7);
- k=cvt[j];
- if (q&1)
- data[i]|=k;
- else
- data[i]&=(cvtn[j]);
- return (*this); };
- BitRef& operator = (const BitRef &q)
- { int i; i=q.GetBit();
- (*this)=i; return (*this); };
- // Note: default copy constructor and destructor are correct
- }; // end BitRef
-
- The point of "BitRef" is to be returned as a temporary in a variety
- of "bit" objects. For instance:
-
- class halfword { // 16 bits on many machines
- char[2] data;
- public
- BitRef operator[] (int i) { return BitRef(i,data); };
- // etc.
- };
-
- and then one codes:
-
- halfword x;
- x = 13;
- x[0]= 1; // etc.
-
- Now, I am less interested in the particular virtues and vices of
- BitRef per se than in what to do _in general_ with helper objects of
- that kind. Note carefully that in the normal course of events, BitRef
- will never be formally declared. It will arise, normally, as a temporary
- in various objects' operator[]. There are many such potential objects.
-
- Optimizing such objects can be important, especially if they "help"
- functions like operator[], because they may appear in inner "for" loops.
-
- I especially wonder about "new" and "delete".
-
- For machines with enough registers, one presumes that the above code
- could work out fairly nicely, as is. Each data element of an instance
- of BitRef could imaginably have both of its small pieces optimized into
- a register, especially since the compiler, since it creates it, is in
- full control of how long the instances live.
-
- For a PC-type machine, however, such optimization seems unlikely (is
- that so?). Therefore, _if_ the compiler's generation of "temps" uses
- new and delete, one would be tempted to add something like the following
- to BitRef
-
- static short int two[2];
- static BitRef *twop[2];
-
- Their init would set both members of two to "false" and twop to null.
- The overloaded new would see if either value of "two" were false. If
- either was, it would know it they not in use and return a non-null value of
- the corresponding twop. Delete would simply check twop and mark the
- corresponding member of two "false" if it matched. If there were more
- than two outstanding BitRefs, the normal new/delete would be used.
-
- The upshot of this is that there typically be only two calls to the
- ::new function and very few to ::delete, because few expressions would
- need more than two BitRefs to complete the work. And, the memory
- allocation overhead could be generally dispensed with, which may be worth
- a lot of performance.
-
- On the other hand, if the compiler were smart enough to add its temps to
- the regular program push/pop stack (thus avoiding new and delete altogether),
- there would be no net advantage to the overload, even with no optimization.
- Which is typically done?
-
- In the case of BitRef itself, the optimization question is of some interest,
- because it may be sensible to separate "loc" into two values in the object,
- passing them into the constructor, up front, which may aid run time
- performance at least some of the time (eg halfword[4]), if one did not wipe
- out the gains by introducing added memory allocation by exceeding some
- internal threshhold or other.
-
- Is all/any of this reasonable analysis?
-
- --
- Larry W. Loen | My Opinions are decidedly my own, so please
- | do not attribute them to my employer
-