Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CPlusPlusNotesForProfessionals.pdf
Скачиваний:
47
Добавлен:
20.05.2023
Размер:
5.11 Mб
Скачать

Chapter 144: Optimization

When compiling, the compiler will often modify the program to increase performance. This is permitted by the as-if rule, which allows any and all transformations that do not change observable behavior.

Section 144.1: Inline Expansion/Inlining

Inline expansion (also known as inlining) is compiler optimisation that replaces a call to a function with the body of that function. This saves the function call overhead, but at the cost of space, since the function may be duplicated several times.

// source:

int process(int value)

{

return 2 * value;

}

int foo(int a)

{

return process(a);

}

// program, after inlining:

int foo(int a)

{

return 2 * a; // the body of process() is copied into foo()

}

Inlining is most commonly done for small functions, where the function call overhead is significant compared to the size of the function body.

Section 144.2: Empty base optimization

The size of any object or member subobject is required to be at least 1 even if the type is an empty class type (that is, a class or struct that has no non-static data members), in order to be able to guarantee that the addresses of distinct objects of the same type are always distinct.

However, base class subobjects are not so constrained, and can be completely optimized out from the object layout:

#include <cassert>

struct Base {}; // empty class

struct Derived1 : Base { int i;

};

int main() {

//the size of any object of empty class type is at least 1 assert(sizeof(Base) == 1);

//empty base optimization applies

assert(sizeof(Derived1) == sizeof(int));

GoalKicker.com – C++ Notes for Professionals

676

}

Empty base optimization is commonly used by allocator-aware standard library classes (std::vector, std::function, std::shared_ptr, etc) to avoid occupying any additional storage for its allocator member if the allocator is stateless. This is achieved by storing one of the required data members (e.g., begin, end, or capacity pointer for the vector).

Reference: cppreference

GoalKicker.com – C++ Notes for Professionals

677