BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Help reducing object instance size
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 2:43 am    Post subject: Help reducing object instance size Reply with quote



Hi, I would like to get some tips in reducing the size of an object in
my program. Right now, by my own caculations, it turn out that each
object uses about 160bytes, even though InstanceSize reports as only
60bytes. When I have 10,000 of these objects in memory, the program
takes up to 10mb, and 300,000 objects takes up 54mb. This is way too
large.

Is there anything i can do, short of abandoning the whole object thing
and turning it all into records? Its much more simpler to work with
objects than records.

This is the interface of my object. Any help would be greatly
appreciated...

TLMElement = class(TObject)
protected
FTop:integer;
FLeft:integer;
FHeight:integer;
FWidth:integer;
FOnResize:TNotifyEvent;
FMaxWidth:integer;
FMaxHeight:integer;
FObeyMaxWidth:boolean;
FObeyMaxHeight:boolean;
FRight:integer;
FBottom:integer;

infostr:string;
procedure SetInfo(Key: string; val : string);
function GetInfo(Key: string) : string;

public
ChildElements:TList;

constructor Create(UseDefaults : boolean = true);
destructor Destroy; override;

property Top : Integer read FTop write FTop;
property Left : Integer read FLeft write FLeft;
property Width : Integer read FWidth;
property Height : Integer read FHeight;
property OnResize: TNotifyEvent read FOnResize write FOnresize;

property Right : Integer read FRight;
property Bottom : integer read FBottom;

property MaxWidth : Integer read FMaxWidth write FMaxWidth;
property MaxHeight : Integer read FMaxHeight write FMaxHeight;
property ObeyMaxWidth : boolean read FObeyMaxWidth write
FObeyMaxWidth;
property ObeyHeight : boolean read FObeyMaxHeight write
FObeyMaxHeight;

procedure DoLayoutNotifyOnResize;
procedure DoLayoutSilent;

function AddChildElement: TLMElement;
procedure OnChildElementResizeEvent(sender:TObject);

property Info[Key: string] : string read GetInfo write SetInfo;
end;

Back to top
Nicholas Sherlock
Guest





PostPosted: Tue Jan 10, 2006 5:22 am    Post subject: Re: Help reducing object instance size Reply with quote



Johan Abdul Aziz wrote:
Quote:
Right now, by my own caculations, it turn out that each
object uses about 160bytes

What are these "calculations"? You're not looking at the memory usage
reported by the Windows task manager, are you? Using an alternate memory
manager such as FastMM4 (Google) will likely help, but you're still
going to be using 20MB minimum for the 300,000 objects you mention.

Cheers,
Nicholas Sherlock

Back to top
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 5:46 am    Post subject: Re: Help reducing object instance size Reply with quote



Yeah, i am using something like task manager (not a proper memory
profiler, I can't find any that actually helps me identify how much
memory is being allocated for each variable or object). But it does
give me a general idea of how much each object is taking,

(mem for 300k - mem for 0 objects) / 300,000

I used memproof and still come out to about 180bytes per object, using
that calculation.

I'm also using Delphi 2006, so it does use fastmm by default. So is
there anyway i can optimize these objects to use less memory? Or have I
hit a wall, and the only way to go is records?

Back to top
Tom de Neef
Guest





PostPosted: Tue Jan 10, 2006 6:44 am    Post subject: Re: Help reducing object instance size Reply with quote

"Johan Abdul Aziz" <johan.aziz (AT) gmail (DOT) com> schreef in bericht
news:1136861035.693253.78270 (AT) g14g2000cwa (DOT) googlegroups.com...
Quote:
Hi, I would like to get some tips in reducing the size of an object in
my program. Right now, by my own caculations, it turn out that each
object uses about 160bytes, even though InstanceSize reports as only
60bytes. When I have 10,000 of these objects in memory, the program
takes up to 10mb, and 300,000 objects takes up 54mb. This is way too
large.

Is there anything i can do, short of abandoning the whole object thing
and turning it all into records? Its much more simpler to work with
objects than records.

This is the interface of my object. Any help would be greatly
appreciated...

TLMElement = class(TObject)
protected
FTop:integer;
FLeft:integer;
FHeight:integer;
FWidth:integer;
FOnResize:TNotifyEvent;
FMaxWidth:integer;
FMaxHeight:integer;
FObeyMaxWidth:boolean;
FObeyMaxHeight:boolean;
FRight:integer;
FBottom:integer;

infostr:string;
procedure SetInfo(Key: string; val : string);
function GetInfo(Key: string) : string;

public
ChildElements:TList;

constructor Create(UseDefaults : boolean = true);
destructor Destroy; override;

property Top : Integer read FTop write FTop;
property Left : Integer read FLeft write FLeft;
property Width : Integer read FWidth;
property Height : Integer read FHeight;
property OnResize: TNotifyEvent read FOnResize write FOnresize;

property Right : Integer read FRight;
property Bottom : integer read FBottom;

property MaxWidth : Integer read FMaxWidth write FMaxWidth;
property MaxHeight : Integer read FMaxHeight write FMaxHeight;
property ObeyMaxWidth : boolean read FObeyMaxWidth write
FObeyMaxWidth;
property ObeyHeight : boolean read FObeyMaxHeight write
FObeyMaxHeight;

procedure DoLayoutNotifyOnResize;
procedure DoLayoutSilent;

function AddChildElement: TLMElement;
procedure OnChildElementResizeEvent(sender:TObject);

property Info[Key: string] : string read GetInfo write SetInfo;
end;


There's no indication how big the infoString is and what the average
population of the childElements is. If you really work on it - using words
instead of integers, array indexes instead of the childElements list,
records instead of objects - you might half your memory requirements.
You'd double the complexity of your code and by the time you are finished
debugging PCs sell with 1Gb as a minimum. Think hard if memory is really
what you should be concerned about.
Tom



Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 10, 2006 9:15 am    Post subject: Re: Help reducing object instance size Reply with quote

"Johan Abdul Aziz" <johan.aziz (AT) gmail (DOT) com> wrote


Quote:
Hi, I would like to get some tips in reducing the size of an object
in my program.

I agree with Tom. "Don't bother."


[...]
Quote:
FMaxWidth:integer;
FMaxHeight:integer;
FObeyMaxWidth:boolean;
FObeyMaxHeight:boolean;

You can save the two Booleans by storing -MaxWidth/Height to indicate
they need not actually be obeyed.

You can still have the old MaxWidth/Height and ObeyMaxWidth/Height
properties, it just computes them differently in the accessor methods.


Quote:
FRight:integer;
FBottom:integer;

Don't store these, compute them.


Quote:
public
ChildElements:TList;

*Don't do that*. Hide it behind a read-only property.

Groetjes,
Maarten Wiltink



Back to top
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 9:23 am    Post subject: Re: Help reducing object instance size Reply with quote

(infostr is 40b on average and for the majority of objects,
cheldElements remain un-instantiated)

Thanks Tom, your tips were exactly what I thought as the last resort
that I didn't want to have to go to.

Appreciate the second opinion guys, Just needed confirmation I haven't
missed any optimizations techniques. I can rest easy now knowing I've
done my practical best...

Back to top
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 9:49 am    Post subject: Re: Help reducing object instance size Reply with quote

Thanks for the tips Maarten, I'm doing all of it!

Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 10, 2006 10:38 am    Post subject: Re: Help reducing object instance size Reply with quote

"Johan Abdul Aziz" <johan.aziz (AT) gmail (DOT) com> wrote


Quote:
Thanks for the tips Maarten, I'm doing all of it!

Aren't "field mangling" and "don't bother" mutually exclusive?

Seriously, I think it's a good thing to see how you can play with
fields and properties and the methods between them. But counting
bytes is on par with counting cycles in my world. Not worth the
trouble.

By the way, since you derive from TObject which has no fields,
would switching to records have gained you _any_ memory?

Groetjes,
Maarten Wiltink



Back to top
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 11:05 am    Post subject: Re: Help reducing object instance size Reply with quote

Not sure what you mean by field mangling, but most of what you said
seemed logical and is probably what I should have done in first place,
wether i was byte counting or not. (Although I'm having second thoughts
about -FWidth/FHeight thing)

I assumed that using objects carries some memory overhead, thats why it
would be more effeicient to use a straight record. Am i wrong?

Also, The reason why I'm taking so much pain doing this object right,
because it forms the basis of a hierarichal gui layout system that
would be the infrastructure of many programs i would be making in the
future. I don't know how much stress I would be putting on it, but I
might as well optimize while its still fresh. I'm also using it in a
program which in a certain cicumstance could possibly hold an object
for every word in the scrabble dictionary, which would run into the
hundreds of thousands.

Thanks for the advice though, i'll try to rermember that, while
exploring the world of delphi.

Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 10, 2006 12:47 pm    Post subject: Re: Help reducing object instance size Reply with quote

"Johan Abdul Aziz" <johan.aziz (AT) gmail (DOT) com> wrote


Quote:
Not sure what you mean by field mangling, but most of what you said
seemed logical and is probably what I should have done in first place,
wether i was byte counting or not. (Although I'm having second thoughts
about -FWidth/FHeight thing)

The usual case is that a property has a backing field that looks very
much like the property itself. At the other end of the scale are computed
properties which sometimes look very different internally from what the
user (client programmer) sees. Here, I meant saving a field by playing
tricks with another field, so that it's made to store the information
for two properties at once.


Quote:
I assumed that using objects carries some memory overhead, thats why
it would be more effeicient to use a straight record. Am i wrong?

Every instance allocates what amounts to a record. The first field is
a pointer to its classtype (represented by the Virtual Method Table for
the type) and after that come all the inherited and introduced fields
in source order. TObject introduces no fields, so an instance of your
class only needs space for its own fields. Plus four bytes per instance
for the classtype pointer; you'd save that. (Sometimes I do talk first
and think later.)

There is also per-class overhead - the VMT had to be stored somewhere.
But this is only once per class.


Quote:
Also, The reason why I'm taking so much pain doing this object right,
because it forms the basis of a hierarichal gui layout system that
would be the infrastructure of many programs i would be making in the
future. I don't know how much stress I would be putting on it, but I
might as well optimize while its still fresh. I'm also using it in a
program which in a certain cicumstance could possibly hold an object
for every word in the scrabble dictionary, which would run into the
hundreds of thousands.

The eternal question - optimise for what? Speed or size? Or, perish
the thought, transparency and maintainability of your code?

Optimisation is not to be avoided always, but premature optimisation is.
It's a small step to observing that any time you're tempted to optimise
for its own sake, it's premature. Wait until you notice a program
running unexpectedly, unacceptably slow.

One of the advantages of using classes is that as long as you don't
change the interface, nobody cares what happens in the implementation[0].
In other words, you _always_ have the opportunity to go back and
optimise something. Nothing will break. So go back only when you find
you must, in the safe knowledge that you don't _need_ to turn out
optimal code the first time, every time.

*All* code optimisation is premature if you're not using an optimal
design and algorithms. Things like having an object for every word in
the dictionary cause some people to worry about memory usage; others
to review the choices that led to it. I bet it would be possible to
make do with fewer objects. (If this is a GUI object, using "virtual"
UI techniques you should only need objects for those things that are
visible. For example.)


Quote:
Thanks for the advice though, i'll try to rermember that, while
exploring the world of delphi.

I was hoping you would. Properties are a good thing to be at ease with.
They're very flexible and very useful. Using them to good effect can
work miracles for the modularity of your programs.

Groetjes,
Maarten Wiltink

[0] For derived classes, the interface includes protected elements.



Back to top
Johan Abdul Aziz
Guest





PostPosted: Tue Jan 10, 2006 1:44 pm    Post subject: Re: Help reducing object instance size Reply with quote

Wow, you certainly gave me alot of meat to chew on. Appreciate the time
you're giving me. In a way, your "prototype first, optimize later"
advice is actually rather comforting Smile I actually got my program down
from > 300mb to about 50mb, but I guess got high on optimize mania, and
didn't know when to stop! Next time, I'll cross the bridge once I reach
it ...

Quote:
TObject introduces no fields, so an instance of your
class only needs space for its own fields. Plus four bytes per instance
for the classtype pointer; you'd save that.

Is that all? That's almost nothing. Makes me wonder now why anyone
would want to use records anymore ...

Quote:
(If this is a GUI object, using "virtual"
UI techniques you should only need objects for those things that are
visible. For example.)

Sounds complicated, but I guess it's less optimal to keep 100k of
objects in memory. (Although, i must still admit, it'll be a whole
alot easier that way. I see what you mean though, can't have the cake
and still eat it )


Back to top
Paul Dunn
Guest





PostPosted: Tue Jan 10, 2006 3:02 pm    Post subject: Re: Help reducing object instance size Reply with quote

Maarten Wiltink wrote:

Quote:
public
ChildElements:TList;

*Don't do that*. Hide it behind a read-only property.

Just curious, but what is wrong with making that public? I admit I've never
understood the whole public/private thing - I like everything to be
accessible to everyone. Why should that not be the case?

D.



Back to top
Bruce Roberts
Guest





PostPosted: Tue Jan 10, 2006 4:40 pm    Post subject: Re: Help reducing object instance size Reply with quote


"Johan Abdul Aziz" <johan.aziz (AT) gmail (DOT) com> wrote

Quote:
Hi, I would like to get some tips in reducing the size of an object in
my program. Right now, by my own caculations, it turn out that each
object uses about 160bytes, even though InstanceSize reports as only
60bytes. When I have 10,000 of these objects in memory, the program
takes up to 10mb, and 300,000 objects takes up 54mb. This is way too
large.

With an instance size of 60 you are getting small enough that the overhead
becomes a significant percentage of memory consumption. For example, each
one of your objects typically involves up to three memory fragments: the
instance, infostr contents, and ChildElements instance. Each of these
fragments, IIRC, has a memory block overhead of 4 bytes. In addition the
string has a further 8 bytes of overhead for each non-empty string. Just to
round things out memory fragment allocation is rounded up to the nearest 4
byte boundry, meaning an average waste of 2 bytes per fragment.

By my calculation this is 42 bytes of overhead per instance. Ovheard that
is probably going to be incurred regardless of using records or class
instances, integers or words. 12MB of overhead on 300 000 objects.

Your choices, as I see them, are to
a) Don't worry about it. A typical new system has virtual space mesured
in GB and at least 10 times requirements in main memory. IMO within 2 years
main memory is also going to be measured in GB, and virtual space will
approach TB.
b) Rework the design. Is it really necessary to store 300 000 discrete
factums? Perhaps there are approaches where the time penalty involved is
sufficiently small to make the space / time trade off favor smaller.

If you are working on your first approach to the problem, my advice would
be similar to Maarten's. Get it working while favoring maintainability. If
you have the luxury of more time to spend on the problem after the first
iteration, you will probably also have numerous ideas of how to improve the
data structures and algorithms.

Just to make life intesting: You need also consider memory fragmentation.
If your objects are relatively static you don't have any real worries.
(Unless of course they are not entirely static and the software has to run
continuously for more than a few hours.) However if the data structure is
fairly dynamic you will have to spend some time designing allocation and
deallocation strategies that won't completely fragment memory space and run
a machine out of memory.



Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 10, 2006 5:23 pm    Post subject: Re: Help reducing object instance size Reply with quote

"Paul Dunn" <paul.dunn4 (AT) ntlworld (DOT) com> wrote

Quote:
Maarten Wiltink wrote:

public
ChildElements:TList;

*Don't do that*. Hide it behind a read-only property.

Just curious, but what is wrong with making that public?

Short (and mostly wrong) answer: someone could free your list for you
while you're not looking.

A better anwer that I can't do justice in this small space would be
that it allows you more control over what another programmer can do
with your list, because it can be a heavily subclassed list with lots
of checks and notifications when items are added or removed. And the
object can't be swapped out arbitrarily because the property is
read-only.

The best short answer is that it lets you write this accessor method:

procedure SetChildElements(const Value: TList);
begin
ChildElements.Assign(Value);
end;

This is a special case of the previous argument. You still can't swap
out the list object, but you _can_ replace all its items at once in a
single assignment.

Quote:
I admit I've
never understood the whole public/private thing - I like everything
to be accessible to everyone. Why should that not be the case?

That's practically a guarantee that you'll write code that's heavily
dependent on the internals of every other class. Keeping the interface
of a class small makes it more reuseable and adaptable.

Do you have many derived classes and overridden methods?

Groetjes,
Maarten Wiltink



Back to top
Hans-Peter Diettrich
Guest





PostPosted: Tue Jan 10, 2006 8:25 pm    Post subject: Re: Help reducing object instance size Reply with quote

Johan Abdul Aziz schrieb:
Quote:
Hi, I would like to get some tips in reducing the size of an object in
my program. Right now, by my own caculations, it turn out that each
object uses about 160bytes, even though InstanceSize reports as only
60bytes.

InstanceSize is the better guess, memory allocation does not always
reflect the really used memory.

Quote:
Is there anything i can do, short of abandoning the whole object thing
and turning it all into records? Its much more simpler to work with
objects than records.

Records won't help much, a reduction of not much more than 4 bytes per
object. I you really want to save a few bytes, reduce the Integer values
to Word or SmallInt, if applicable. Also sort the fields by size,
largest fields first. The strategy is the same as for records...

DoDi

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.