views:

239

answers:

7

Hi All,

Does anyone have a resource for C++ memory optimization guidelines? Best practices, tuning, etc?

As an example:

Class xxx {

    public: 
        xxx();
        virtual ~xxx();

    protected:

    private:

};

Would there be ANY benefit on the compiler or memory allocation to get rid of protected and private since there there are no items that are protected and private in this class?

UPDATE: What is a programmer does this:

Class xxx {

    public: 
        xxx();
        virtual ~xxx();

    public:
        more stuff();
        more();

   ifndef __BUILD_WIN__
      public:
        even more();
        envenmore2();
   endif
    protected:

    private:

};
+8  A: 

Does anyone have a resource for C++ memory optimization guidelines? Best practices, tuning, etc?

That depends a lot on both your compiler and target environment (RISC, Unix/Linux, Windows). Most compilers will have such information.

There are utilities out there that enable you to trace memory leaks so that you can fix them during test. If you are going to dynamically allocate a lot of things (which usually is the case with C/C++), try to make sure you deallocate everything before destroying an object. To do this:

  • If you value memory over processor, use smart pointers.
  • If your class has any member variables that are pointers, make sure your destructor frees each one of the. Group your member variables together on your source code so that it's easy to compare those variables with the destructor.
  • Avoid dynamic memory allocation whenever possible to avoid leaks. Prefer std::string over dynamic allocated char*, etc.

Would there be ANY benefit on the compiler or memory allocation to get rid of protected and private since there there are no items that are protected and private in this class?

No, if I'm not mistaken, protected/private are only checked during compilation, so they don't affect performance even if there were items under the keywords.

Furthermore, it's important to understand that the compiler is very inteligent (usually more than the programmer) so it will optimized away anything it can; For example, let's you declare a variable, int a, inside your constructor. And let's say you don't use it at all, you just forgot it there. Most of the compilers won't even save stack space to those variables. Others will need the user to activate Optimization so that this happens, but as a rule-of-thumb, your production version of any program should be compiled with optimization enabled, even if not on full.

About the update, that thing you looked at are pre-processors directives and are being used to do what is called selective compilation. Take a look here.

Bruno Brant
@bruno - thanks, helpful. compiler are smarter than the programmers, but programmers write compilers, so at least a *few* programmers have to be smart enough to make the compiler do all of this! Now to see how XCode will tell me of unused items because it would be good to know!
ML
@ML: I never used XCode (it's an Apple targetted IDE, isn't it?) but there are probably ways of doing it. Compilers hold the knowledge of many top programmers, that's the reason why they are more intelligent than the average programmer. Kasparov is the best chess player alive, but was beaten by a software created by people! (and that's what I love about computers, even though I wish Kasparov could outsmart DeepBlue).
Bruno Brant
Compilers are only "smarter" than programmers because they can consider multiple optimizations at once much more easily than a human. The individual optimizations may not be that difficult, but consistently applying all of them at the same time is.
mskfisher
@Bruno: http://www.nybooks.com/articles/23592
titaniumdecoy
@bruno - take a look at my update to the post. Does this change your thoughts? Just stupid cruft the programmer did?
ML
@ML: That's selective compilation, used in order to compile the same source against two different environments. But it's missing a "#" before the ifndef and the endif.
Bruno Brant
@titaniumdecoy: excelent article, I just loved it.
Bruno Brant
@bruno - oh I know it is selective compilation with the ifdef's but look above that where he stated public: twice. I just find this type of sloppiness unacceptable and it makes me automatically think about performance/optimization
ML
@ML: Oh, sorry. Didn't noticed the double public. It makes no difference, though it's uncommon to specify it twice. However, I've seen some projects where you had to specify it before *every* member, because it made visibility more clear to the reader.
Bruno Brant
I strongly disagree with the `destructor` comment: don't use raw pointers within a class... you've forgotten the copy and assignment operations there and they will cause UB.
Matthieu M.
@Matthieu: I actually agree with you. If I follow your thoughts correctly, one should use smart pointers or other structures. However, sometimes, performance is crucial (embedded systems) so we go with raw poiters.
Bruno Brant
+2  A: 

Well the compiler wouldn't have to parse them, so there's that benefit to the compiler. For what that's worth (not very much).

There should be no memory use difference.

Other than that, the only benefit I can think of is there's less cruft for someone reading the code to have to deal with (not that it's particularly burdensome in your example).

Michael Burr
I also agree that code reading is easier if you ommit the unnecessary keywords.
Bruno Brant
A: 

public, protected and private keywords, do not make it into object files at all so there is no benefit at all.

In general

  • Try to avoid allocating and freeing memory, reuse whenever possible. Walking the heap is especially slow.
  • Free memory when you are finished with it. Don't leave in hanging around unless there are strong performance reasons for doing so.

Truth is, unlike Java, when programming in C++, you always need to think about memory management to avoid leaks. Optimization therefore comes more naturally than say Java

doron
@deus I almost never think about memory management when I program in C++.
anon
Should read: "Truth is, unlike Java, C++ lets you write and use wrappers to give you deterministic automatic memory management, so you never need to think about memory management to avoid leaks."
GMan
A: 

As far as general guides, there's What Every Programmer Should Know About Memory, but I'm not sure it's what you're looking for.

One general guideline for optimizing memory inside a struct or class is to order your data members from largest to smallest. This prevents excess padding from wasting space in your struct or class.

As to your question I think it's been suitably answered, but you can compare yourself using sizeof().

Dan Olson
A: 

Would there be ANY benefit on the compiler or memory allocation to get rid of protected and private since there there are no items that are protected and private in this class?

No. AFAIK, non-virtual methods doesn't increase size of class instance.

Does anyone have a resource for C++ memory optimization guidelines?

1) If you are concerned about performance, use profiler (AQtime, for example). Do not guess, use tools.
2) In general, it is not a good idea to frequently (several *millions* times per second) allocate and deallocate memory (using new/delete), especially large blocks. ACcording to my experience such usage results performance loss. If you frequently need to allocate large block of memory withing the same routine (using new or std::vector), consider reusing the same block in the next call (this will be tricky in multithreaded app). I.e. instead of

void doStuff(int memSize){
    std::vector<char> buf(memSize);
    //..some code here
}

use something like this:

void doStuff(int memSize){
    static std::vector<char> buf;
    if (buf.size() < memSize)
        buf.resize(memSize);
    //..some code here
}

But only when necessary and only if you are absolutely sure that this routine cannot be called from several separate threads simultaneously. (To make it multithread-compatible, you'll need some tricks - either mutexes, or the "pool" of several buffers)
3) Allocating more than 1 megabytes (for windows) or 8 megabytes (for linux) on stack will cause your program to crash (stack overflow for win, segfault on linux) unless you have specified stack size during compile time. Example:

void doStuff(){
    char buf[1024*1024*12];//use new[] or std::vector instead of this.
    //some code here
}

That's all I can think of.

SigTerm
A: 

It really depends on your application. If you are doing simulations or any kind of scientific computing where you are doing floating point calculations on large arrays of memory then there are a lot of things you can do.

  • Optimize for cache reuse (cache blocking, padding, etc)
  • Optimize to minimize TLB hits (page faults)
  • Arrange your data as structures of arrays, not as arrays of structures
  • Avoid unnecessary memory clears
  • Avoid reallocating memory, reuse instead

If you need to have many small objects, look at things like the flyweight design pattern or object pools.

As for worrying about private and protected declarations, don't. They are only relevant for compilation to enforce encapsulation and data hiding, and do not affect the generated binary.

mch
+1  A: 

There's "Efficient C++: Performance Programming Techniques" by Dov Bulka and David Mayhew. I don't think it's ground-breaking, but it certainly is an interesting read that teaches a few basics.

sbi