3

私は科学計算のためのプログラムを書いています、そして私の最大の関心は(正しさの後)スピードです。最近、私も読みやすいコードが必要であることに気づきました。:)

書く代わりに

for (int k=0;k!=10;k+=1)
   array[k] = fun(a, k);

書くことを考えています

class fun_t {
private:
   type a;
public:
   fun_t(type in) : a(in) {};

   type operator() (int k) {
      ...computation...
   }
};
...
fun_t fun(a);
for (int k=0;k!=10;k+=1)
   array[k] = fun(k);

関数オブジェクトのスタイルは最初の例と同じくらい高速ですか?両方で同じインラインを期待できますか?より良い方法はありますか?(ここではアイデアを提示しているだけであり、これは実際のコードではないことに注意してください。)

4

3 に答える 3

4

重い計算は関数内で実行されると思います。それと比較して、直接関数呼び出しとメンバー関数呼び出しの違いは重要ではありません。

于 2012-10-25T11:39:34.170 に答える
2

妥当なコンパイラからも同じインライン化が期待できます。の呼び出し先は、の呼び出しとoperator()同じように、コンパイル時にわかりますfun(a,k)

私が見る違いは、へのアクセスにありますa。関数の場合、何かfunをパラメータとして渡します。宣言がないと、これが、のコピー、への参照、またはから構築された他のタイプであるかどうかを確認できません。funaaa

ファンクターの場合は、 1回fun_tコピーしてファンクターを作成しますa。あなたは(名目上)fun_t*asを渡してthisからoperator()、としてaアクセスされthis->aます。すべてがインライン化されてオプティマイザが終了すると、余分な間接参照は排除される可能性がありますが、そうでない場合もあります。おそらくコンパイラーによって発行された命令を調べることによって、特定のケースをチェックする必要があります。

于 2012-10-25T11:56:57.037 に答える
1

ループ構造を変更することで小さな最適化を行うことができるかもしれませんが、これらの主な目的は速度の向上ではありません。

速度を向上させたい場合は、プロファイリングする必要があります。特に低速の操作であり、各実行が他の実行に依存していない場合fun(a,k)は、スレッドに分割して、それぞれを独自のスレッドで実行することを検討する必要があります。

直列ではなく並列でコレクションを操作するようになる新しいAPIがあります。これからのエキサイティングな時代。

于 2012-10-25T11:41:25.323 に答える