サーチ…


前書き

コンパイルするとき、コンパイラはプログラムを変更してパフォーマンスを向上させることがよくあります。これは、 if-ifルールによって許可され、観察可能な振る舞いを変更しないすべての変換を許可します。

インライン展開/インライン展開

インライン展開(インライン展開とも呼ばれる)は、関数の呼び出しをその関数の本体で置き換えるコンパイラの最適化です。これにより、関数呼び出しのオーバーヘッドは節約されますが、関数が複数回複製される可能性があるため、領域を犠牲にしてしまいます。

// 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()
}

インライン化は、関数呼び出しオーバーヘッドが関数本体のサイズに比べて重要な、小さな関数に対して最も一般的に行われます。

空の基本最適化

型が空のclass型(つまり、静的でないデータメンバを持たないclassまたはstructであっても、オブジェクトまたはメンバサブオブジェクトのサイズは、少なくとも1にする必要があります。同じタイプの異なるオブジェクトのアドレスは常に区別されます。

ただし、基本classサブオブジェクトは制約がなく、オブジェクトレイアウトから完全に最適化することができます。

#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));
}

allocator-aware標準ライブラリクラス( std::vectorstd::functionstd::shared_ptrなど)は空の基本最適化を頻繁に使用して、アロケータがステートレスであればそのアロケータメンバの追加ストレージを占有しないようにします。これは、必要なデータメンバーの1つ(例えば、 vector beginend 、またはcapacityポインタ)を格納することによって実現されます。

リファレンス: cppreference



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow