web-dev-qa-db-ja.com

`static`の使用は私のコードの速度にどのように影響しますか?

オンラインでエクササイズを解いていたときに、ある時点で文字列の最初と最後から「」を削除する必要がありました。これは私のコードでした:

_void static inline process_value(std::string &value) {
    if (value.back() !='>') {
        value = value.substr(1, value.size()-2);
    }
}
_

このベンチマークループから呼び出されます:

_static void UsingStatic(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
      std::string valor("\"Hola\"");
      process_valueS(valor);
    // Make sure the variable is not optimized away by compiler
    benchmark::DoNotOptimize(valor);
  }
}
_

好奇心だけで ベンチマークをやりました

  • コンパイラ: Clang-9.0
  • std: c ++ 20
  • optim: O3
  • STL: libstdc ++(GNU)

その間、_process_value_からstaticを削除して、_void inline process_value_を他の点では同じにすることにしました。驚いたことに、それはより遅かった。

静的とは、関数がファイル専用であることを意味するだけだと思いました。しかし ここ は、「「静的」とは、可能であれば関数がコンパイラーによってインライン化されるべきであることを意味します」と述べています。しかしその場合、私が静的を削除したとき、結果は変更されるべきではなかったと思います。今私は混乱しています、関数を単一の_.cpp_に区切る以外にstaticは他に何をしますか、それはパフォーマンスにどのように影響しますか?

QuickBenchの逆アセンブリは、NoUsingStaticキーワードがコンパイラーに合法であるようにしているにもかかわらず、inlineループがインライン化する代わりに実際に_process_value_を呼び出すことを示しています。しかし、UsingStaticdoesは、_process_valueS_の呼び出しをインライン化します。コンパイラの意思決定におけるその違いは、おそらくパフォーマンスの違いを説明しますが、clangが宣言された単純な関数をインライン化しないことを選択するのはなぜですかvoid inline process_value(std::string &value){ ... }


編集:それは十分に明確ではなかったので質問が閉じられたので、私は質問に関連していない部分を削除しました。しかし、いくつかの情報が不足している場合はコメントで教えてください

7
Pablochaches

inlineはコンパイラーへのアドバイスにすぎません。コンパイラーは特定のコードを実際にインライン化してもしなくてもかまいません。

staticキーワードに関して、それがグローバル変数に適用されている場合、コードを個別のコンパイル単位としてコンパイルすると、(前述のように)ファイルスコープが含まれます。したがって、単一のコンパイル単位としてコンパイルすると、静的グローバル変数を他のファイルからアクセスできるようにすることもできます。つまり、実際には、グローバル静的変数のスコープはファイルではなく、コンパイル単位(1つのファイルである場合とそうでない場合がある)です。

ただし、変数ではなくグローバル静的関数があるので、グローバル静的関数としてどこからでもアクセスできます。

EDIT:以下のコメントで@Peter Cordesによって提案されているように、インラインと静的を同時に備えた実際の混乱である可能性があるため、公式ドキュメント( https://en.cppreference.com/w/cpp/language/inline )は、インライン関数(およびC++ 17以降の変数)の再定義は非静的でなければならないことを示しています。

0
Hack06