c++ memory optimization

B

BCC

Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

Thanks,
Bryan
 
J

Jerry Coffin

Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space?

At least as usually implemented, member functions (like other code) only
take up space once, regardless of the number of objects of the class you
create.
Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

It's probably not a useful answer to the question, but the lightest
possible object is an empty base class (which can have zero size). Any
other object must occupy at least one byte, even if it has no data.
There's no particularly strong relationship between being a container
and being lightweight -- it's possible (maybe even likely) but that's
about as strongly as you can put it.
 
N

NFish

BCC said:
Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

Thanks,
Bryan

You might be surprised at how your OS manages memory. Mine allocates
memory in 16 byte chunks, so the smallest object I can have with the
standard allocator is 16 bytes.

If your platform behaves similarly and you anticipate having objects
that need less than 16 bytes, you might look into writing a custom
allocator for them.

-Peter
 
E

Evan

BCC said:
Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space?

Functions take up space, but they are small and only occur once per
class rather than per object.
Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

Thanks,
Bryan

The only thing really general I can think of is to see if your classes
have virtual functions, and if so, if they need them. If you don't
need them, get rid of them. It will free up the few bytes taken by the
vtable, which is a per-object basis. Of course, doing this is often
not an option.

Other than that, I'd just say look through your class to try to strip
out anything you don't need. You've got really really big objects (a
couple KB each), so it might be possible to cut out something.

Evan
 
G

Gianni Mariani

BCC said:
Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

Assuming (quite possibly wrong) you have predominantly 125k of one type
of object, then the object is around 2Kbytes each ... that's alot of
bytes if you want millions. Do these objects contain strings ?

If you have 125k copies of the same string, that would cause some bloat
- you could use "ATOMS" - each string is checked with hash table of all
atom strings when created and a reference to an existing string is used
when it already exists.

The other option is get a bigger machine. The AMD opteron machines go
to 32 gigs - that would hold 16 million 2048 byte objects....
 
N

Nilesh

BCC said:
Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

I dont know your design but generally it is not a good idea to create
so many objects. Probably you can reuse some objects.

regards,
Nilesh Dhakras.
 
I

Ivan Vecerina

| I have a c++ program that creates hundreds of thousands of objects.
| Eventually, we would like to be able to create millions, but memory is
| limiting us. For example, 125,000 objects currently takes up 286 megs of
| memory.

Over 2k per object: this seems like a lot, unless you have data members
which allocate sub-objects.

| This leads to a couple questions...

Hi Bryan,
First, please be aware that any optimization-related discussion will
imply some platform-specific behaviors -- but the comments below do
apply to most common platforms.

| First, do accessor functions take up space? Are there certain tricks that
I
| should be aware of when designing a class? I am assuming the lightest
| object I can use is just a container with only the necessary members, is
| this right?


Non-virtual member functions add no size overhead per object instance.
The first virtual function added will add an overhead which is typically
that of an additional data member of a pointer type.
Changing the order of data members can also affect the size of a
class/struct (because of alignment constraints). As a rule of thumb,
you may want to sort data members from larger to smaller primitive
types (e.g. double - pointers/long/float - short - bytes).

But these are things that are looked into when optimizing small
data structure. From the size of your individual objects, it
appears that the memory problem is mostly related to data members
that use dynamic storage (e.g. std::string, C++ containers, etc).

| Are there any books or good websites that will help me lighten
| our classes up a bit?

There are too many approaches, depending on the situation.
Most guides will look at low-level details (such as the above).
I think that you should provide more details about your object
instances, so that we can discuss specific approaches...


Regards,
Ivan
 
S

Socketd

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs
of memory.

Do you need to use all the objects at the same time? If not, how about
saving them in a database instead of in container classes?

br
socketd
 
C

Calum

BCC said:
Hi,

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

If you need it leaner,
- use smaller integers, e.g. short, char, int x:4;
- compress into bit fields
- reduce use of STL
- use floats instead of doubles.
- Calculate more fields on the fly instead of storing them
- don't duplicate data - share it using pointers/references
- keep data inline instead of as member objects
- shorten arrays

You have probably thought of these already, but just in case. Why don't
you post the object so we can take a look?
Calum
 
P

Peter van Merkerk

I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

Depending on the situation, the Flyweight pattern described in the book
'Design Patterns' from E. Gamma et al, may help to reduce the memory
usage.
 
N

Nick Keighley

BCC said:
I have a c++ program that creates hundreds of thousands of objects.
Eventually, we would like to be able to create millions, but memory is
limiting us. For example, 125,000 objects currently takes up 286 megs of
memory.

This leads to a couple questions...

First, do accessor functions take up space? Are there certain tricks that I
should be aware of when designing a class? I am assuming the lightest
object I can use is just a container with only the necessary members, is
this right?

Are there any books or good websites that will help me lighten our classes
up a bit?

flyweight pattern.

Best I could find on google was
http://www.dofactory.com/patterns/Patterns.aspx

the code examples are in C# but I'm sure you could convert them to
something sensible.

For patterns in general try "Design Patterns" by Gamma et al (The Gang of Four).
 
J

Jerry Coffin

[ just some comments to make things more specific ... ]
Functions take up space, but they are small and only occur once per
class rather than per object.

More specifically, accessor functions are small -- other functions can,
of course, be larger (but as you said, they're normally per class,
regardless of size).
The only thing really general I can think of is to see if your classes
have virtual functions, and if so, if they need them. If you don't
need them, get rid of them. It will free up the few bytes taken by the
vtable, which is a per-object basis. Of course, doing this is often
not an option.

Again, to be a bit more specific: the vtable itself normally occurs on a
per-class basis, and then each object contains a pointer to its
associated vtable. If you reduce the number of virtual functions, you
reduce the size of the vtable. You only reduce the object size when/if
you can eliminate _all_ virtual functions from the class, in which case
the class becomes smaller by the size of one pointer. One option that's
sometimes worth exploring along this line is whether you can use
templates to handle the polymorphism at compile time instead of using
inheritance to handle it at run-time. That won't always work, but it
can sometimes (especially likely with older code that made little or no
use of templates).

Another point that I don't recall seeing mentioned is that if you're
using this many objects, it's a fair bet that many (perhaps all) are
dynamically allocated. If that's the case, you might be able to save a
fair amount with a custom allocator of some sort.

Many generic allocators round sizes to powers of two, which means that
on average, you can expect the memory allocated for an object to exceed
what it really needs by roughly 25%. It also means that you may see
memory usage go down rather dramatically with even a small reduction in
size -- right now the objects are averaging about 2K apiece, but that
could result from objects that really need as little as 1023 bytes, in
which case reducing each object by one byte would save half the storage
(admittedly, that exact scenario isn't very likely, but it could easily
be that a few dozen bytes or so would cut memory usage in half).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top