1
class MyClass
{
    public:
        MyClass()
        {
            m_dbLoopStart   = 0.0;
            m_dbLoopStop    = 100.0;
            m_dbLoopStep    = 0.001;
        }

        // Which of the following methods complete in a shorter time?

        void Foo1() const   // This one?
        {
            for (double x=m_dbLoopStart; x<=m_dbLoopStop; x+=m_dbLoopStep)
            {
                f(x);
            }
        }

        void Foo2() const   // Or, this one?
        {
            for (double x=m_dbLoopStart; x<=m_dbLoopStop; x+=m_dbLoopStep)
            {
                2.0 * x + 1.0;
            }
        }

    private:
        double m_dbLoopStart, m_dbLoopStop, m_dbLoopStep;

        inline static double f(double x)
        {
            return 2.0 * x + 1.0;
        }
};

Foo1()とのFoo2()うち、どちらがより速く完了しますか?

4

4 に答える 4

3

この場合、クラス定義で定義された関数はデフォルトでインラインであるため、「インライン」の使用は不必要です。
そうは言っても、関数をインラインとして定義しても、関数をインライン化する必要があるわけではなく、インラインとして定義しないからといって、コンパイラが関数をインライン化しないという意味でもありません。

他の人がすでに言ったように、この場合、最適化をオンにしても違いはありません。ループをコードなしに最適化する必要があり、x には m_dbLoopStop の値が割り当てられます (x が何であれ)。

于 2012-01-03T13:46:05.683 に答える
2

インライン関数を使用する場合でも、コンパイラは関数自体の本体をコピーしないことを選択する可能性があり、関数呼び出しが発生します。関数本体を明示的に記述した場合、確実に関数は呼び出されません。

厳密に理論的には、その方が高速です。

于 2012-01-03T13:32:46.453 に答える
1

インライン関数は、関数呼び出しのコストを回避し、オーバーヘッドを返すため、高速になる場合があります。コンパイラは、関数をインライン化しないことを選択する場合があることに注意してください。

ほとんどの変換プログラムでは、関数パラメーターを渡し、パラメーターと関数のローカル ストレージにスペースを割り当てる必要があります。戻り側では、関数のローカル変数を削除する必要があり、通常は値が返されます。

getter や setter などの単純な関数の場合、関数の呼び出しと戻りのオーバーヘッドは、関数内のコードよりも大きくなります。したがって、インライン化すると、これらの関数が高速化されます。

インライン関数は、関数を呼び出す分岐命令も削除します。これにより、プロセッサが命令キャッシュ/パイプラインをクリアする可能性が減少します。最新のプロセッサは、分岐命令の悪影響を軽減するアルゴリズムを実装していますが。

私のプログラミングの実践では、小さな (3 行以下) メソッドをインライン化します。パフォーマンス上の理由でインライン化する場合は、インライン化する前にプロファイリングします。

于 2012-01-16T21:09:04.280 に答える
1

パラメーターを使用してインライン関数を呼び出す場合と、単純にコードのコピー/貼り付けまたは #define マクロを使用する場合とでは、意味上の違いがわずかにあることがよくあります。たとえば、次のマクロと関数について考えてみましょう。

extern void some_extern_function(int x);
#define foo1(x) (some_extern_function((x)), some_extern_function((x)))
void インライン foo2(int x) {some_extern_function(x); some_extern_function(x); }

次に、それらを呼び出すとします。

  extern volatile int some_volatile_int;
  foo1(some_volatile_int);
  foo2(some_volatile_int);

このシナリオでは、インライン関数foo2は のコピーをsome_volatile_int作成し、そのコピーを の両方の呼び出しに渡す必要がありsome_extern_functionます。対照的に、マクロはsome_volatile_int2 回ロードする必要があります。呼び出し規約によっては、どちらのアプローチも他のアプローチよりも高速になる場合があります。

于 2012-01-16T20:41:22.843 に答える