Online Book Reader

Home Category

Professional C__ - Marc Gregoire [419]

By Root 1390 0
constructor and destructor and watching the printout.

In general, the compiler constructs a temporary object whenever your code converts a variable of one type to another type for use in a larger expression. This rule applies mostly to function calls. For example, suppose that you write a function with the following prototype:

void doSomething(const SpreadsheetCell& s);

You can call it like this:

doSomething(5.56);

The compiler constructs a temporary SpreadsheetCell object from 5.56 using the double constructor, which it passes to doSomething(). Note that if you remove the const from the s parameter, you can no longer call doSomething() with a constant; you must pass a variable. You can use C++11 rvalue references, discussed in Chapter 9, to allow passing a constant to doSomething().

You should generally attempt to avoid cases in which the compiler is forced to construct temporary objects. Although it is impossible to avoid in some situations, you should at least be aware of the existence of this “feature” so you aren’t surprised by performance and profiling results.

C++11 move semantics are also used by the compiler to make working with temporary objects more efficient. That’s another reason to add move semantics to your classes.

The Return-Value Optimization

A function that returns an object by value can cause the creation of a temporary object. Continuing with the Person example, consider this function:

Person createPerson()

{

Person newP;

return newP;

}

Code snippet from Person\Person.cpp

Suppose that you call it like this (assuming that operator<< is implemented for the Person class):

cout << createPerson();

Code snippet from Person\Person.cpp

Even though this call does not store the result of createPerson() anywhere, the result must be stored somewhere in order to pass it to operator<<. In order to generate code for this behavior, the compiler is allowed to create a temporary variable in which to store the Person object returned from createPerson().

Even if the result of the function is not used anywhere, the compiler might still generate code to create the temporary object. For example, suppose that you have this code:

createPerson();

The compiler might generate code to create a temporary object for the return value, even though it is not used.

However, you usually don’t need to worry about this issue because the compiler will optimize away the temporary variable in most cases. This optimization is called the return-value optimization.

Use Inline Methods and Functions

As described in Chapter 7, the code for an inline method or function is inserted directly into the code where it is called, avoiding the overhead of a function call. You should mark as inline all functions and methods that you think can qualify for this optimization. However, remember that inlining requests by the programmer are only a recommendation to the compiler, which is allowed to refuse them.

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. Thus, you should read your compiler documentation before wasting a lot of effort deciding which functions to inline.

DESIGN-LEVEL EFFICIENCY


The design choices in your program affect its performance far more than do language details such as pass-by-reference. For example, if you choose an algorithm for a fundamental task in your application that runs in O(n2) time instead of a simpler one that runs in O(n) time, you could potentially perform the square of the number of operations that you really need. To put numbers on that, a task that uses an O(n2) algorithm and performs one million operations would perform only one thousand with an O(n) algorithm. Even if that operation is optimized beyond recognition at the language level, the simple fact that you perform one million operations when a better algorithm would use only one thousand will make your program very inefficient. However, for small inputs, big-O time can be very misleading. An O(n2) algorithm

Return Main Page Previous Page Next Page

®Online Book Reader