Writing Efficient C++

First of all before of writing some tips to write an efficient code using C++, we need to define the term  of efficient code. There are multiple factors to measure the efficiency of any written code like (Speed, Memory Usage, Disk Access, Network use .. etc), so we can say that the efficient program is the program that completes its tasks as quickly as possible within the given circumstances, so the program can be efficient without being fast, if the application domain is mainly prohibitive to quick execution.

Regarding to professional C++ book 2005, there are two approaches to efficiency. The traditional  one is to writing efficient program and  optimizing, or improving the performance and this technique usually relates to Language-Level Efficiency: Some specific, independent code changes such as passing by reference, returning by reference, exception handling .. etc

The second approach is to think about the efficiency from the design point of view, and this named Design-Level efficiency: includes choosing efficient algorithms, avoiding unnecessary steps and  computations, and selecting appropriate design and optimizations. In this post we’ll discuss the first approach which is Language-Level Efficiency.

Language-Level Efficiency

As we previously mentioned, some specific, independent code changes such as passing by reference, returning by reference and so on and we’ll mention some tips and trick related to this.

  • Handling Object Efficiently:
    • Pass-By-Reference
    • Return by Reference
    • Catch Exceptions by reference
    • Avoid creating temporary objects
    • Return Value Optimization
  • Don’t Overuse costly language features
  • Use Inline methods.

Handling Objects Efficiently

  • Pass by reference: 

    Objects should rarely be passed by value to a function or method, as Pass-by-value incurs copying costs that are avoided by pass-by-reference. Assume that you have a class named “ClassA” and you’ll pass an instantiated object to some function to process it, you could write a function that takes a ClassA Object in the following way.

  1. void TestClassA( const ClassA& classAObj)
  2. {/*Test Code*/}

instead of

  1. void TestClassA( ClassA classAObj)
  2. {/*Test Code*/}
  • Return by reference: 

    As you should pass the object by reference to functions, you should also return them by reference from functions in order to avoid unnecessarily copying of the object. And sometimes returning by reference is impossible , such as when you write overloaded operator+ and other similar operators. And take care “You should never return a reference or a pointer to a local object that will be destroyed when the function exits”

  • Catch Exception by reference:

    You should catch exceptions by reference in order to avoid an extra copy. exceptions are heavy in terms of performance.

  1. try{
  2.     …
  3. }
  4. catch(CustomException &e){
  5.     …
  6. }
  • Avoid Creating Temporary Objects: 

    The compiler creates temporary, unnamed objects in several circumstances. for example after writing a global operator+ for a class.

  1. class ClassTest{
  2. private:
  3.     int m_value;
  4. public:
  5.     ClassTest(){}
  6.     ClassTest(double &initialValue):m_value(initialValue){}
  7.     void Set(int value)
  8.     {m_value = value;}
  9. };
  10. const ClassTest operator+(const ClassTest& lhs, const ClassTest& rhs)
  11. {
  12.     ClassTest test;
  13.     test.Set(lhs.m_value+ rhs.m_value);
  14.     return (test);
  15. }

In general, the compiler constructs a temporary object whenever your code converts a variable of one type to another type  This rule applies mostly to function calls. For example, suppose that you write a function like this:

  1. void doSomething(const ClassTest& s);

and you called this function like this: doSomething( 5.5) , The compiler constructs a temporary ClassTest object from 5.5 using the double constructor,which it passes to doSomething(), So generally try to avoid such of these cases in which the compiler is forced to construct temporary objects and you should at least be cognizant of the existence of this “feature” so you aren’t surprised by performance results.

  • Return Value Optimization:

    A function that returns an objects by value can cause the creation of a temporary object.

    1. Person CreatePerson()
    2. {
    3.     Person newP;
    4.     return (newP);
    5. }

Finally, don’t worry about this issue because the compiler will optimize away the temporary variable in most cases. This optimization is called the return value optimization.

Don’t Overuse Costly language features

Several C++ features are costly in term of execution speed: exceptions, virtual methods, and Run-Time Type Information RTTI. If the code efficiency is an important factor for you, then you should consider avoiding these features. Unfortunately, support for exceptions and RTTI incurs performance overhead even if you don’t explicitly use the features in your program should be compiled without support for these features at all.

  1. Class base
  2. {
  3. public:
  4.     base() {}
  5.     virtual ~base() {}
  6. };
  7. class derived : public base {};
  8. int main(int argc, char** argv)
  9. {
  10.     base* b = new derived();
  11.     derived* d = dynamic_cast<derived*>(b); // Use RTTI.
  12.     if (d == NULL) {
  13.         throw exception(); // Use exceptions.
  14.     }
  15.     return (0);
  16. }

and the problem here when dynamic_cast<> fails at run time causing the program to generate segmentation violation exception.

Use Inline Methods

As most of us know that the code for an inline method is inserted directly into the code where it is called, avoiding the overhead of a function call. “However, remember that inlining requests by the programmer are only a recommendation to the compiler. It can refuse to inline the function that you want it to inline.”

On the other hand, some compilers inline appropriate functions and methods during their optimization steps, even if those functions aren’t marked with the inline keyword.

  1. inline void Hello();

Tips To Enhance Technical Skills

I’m writing this post to share some thoughts about improving the technical skills of computer science students, this post will be updated whenever I remember one of my scattering thoughts 😀 Feel free share your thoughts with us in comments, and I’ll feel happy to add them to the post.

  • Practice, Practice, and  Practice to the Infinity –  The direct path to enhance your coding skills. Simply, practice means writing/reading codes. Practice with a defined Goal , practice on things that aren’t easy for you, and always create a schedule or structure to follow.
  • NEVER STOP solving problems on different online judges (TopcoderUVaSPOJCodeforcesUSACO, .. etc)  and participating in online and offline competitions, this will help you to enhance your thinking skills and improve your coding skills by writing bug-free, well-tested, and high-performance code.
  • Learn a different programming language every some period, for example every semester or every year, but be professional in using one of them.
  • NEVER STOP learning new topics and new techniques, and implement them.
  • When you get your summer vacation try to make code re-factoring to the code of your academic projects and document this code, it could be useful for sharing the code online and allowing others to contribute to it. To be honest I never made this, but it’s a very important point.
  • Reading and figuring out the problems of codes that written by different people.
  • Share your code with people to get reviews on your code, you can share it on some of online open source communities like Code project and Sourceforge.
  • Get involved with open source projects, there are multiple open source projects that have many experienced software programmers  working on them.
  • Write a documentation for code written by other people. This helps in understanding the way other people think and program.
  • Try to build a good team with different qualifications, pairing programming with other programmers might increase the quality of code.
  • Seek first to be professional in the basics of computer science ,then to learn the advanced topics.
  • Explain what you know to others, this sometimes helps you to fill the gap in your knowledge, always share your knowledge with others.
  • Don’t hesitate to ask questions on online groups like LinkedIn groups.
  • Attend the online courses on Coursera, Udacity and so on.
  • Broaden your horizons by following some technical magazines, technical blogs,  to be aware of the latest technologies, latest research and projects all over the world.