2009-04-05 10 views
1

私は何度も呼び出される高価な関数を持っていますが、そのパラメータには可能な値のセットが非常に限られています。
ファンクションの戻りコードは引数のみに依存するため、実行可能な引数と対応する戻りコードに対して、静的キャッシュを関数内に保持することが明らかです。パラメータのすべての組み合わせに対して、高価な操作は1回のみ実行されます。
私はこのような状況で常にこのアプローチを使用していますが、うまくいきますが、GCC関数の属性constまたはpureがおそらくこれで私を助けてくれるはずです。GCC関数の属性とキャッシュの比較

誰もこの経験がありますか? GCCがpureconstの属性をどのように使用するのですか?コンパイル時または実行時にのみですか?
私は、関数を呼び出すには十分にスマートであることをGCCに依存している同じパラメータ値に一度だけ

int foo(int) __attribute__ ((pure)) 

として宣言、または保証は一切ありませんし、私はより良い、キャッシング・アプローチに固執することはできますか?

EDIT:私の質問は、キャッシュ/メモ/ルックアップテーブルではなく、GCC関数の属性です。

+0

pureは適用されません。しかしconstは良く見える。 –

答えて

15

あなたはGCC純粋な属性をmemoizationと混同していると思います。

GCCのpure属性を使用すると、ループアンローリングなどの特定の状況で関数が呼び出される回数をコンパイラで削減できます。しかし、それが適切だと考える場合に限り、それがそうすることを保証するものではありません。

あなたが探していると思われるものは、お使いの機能のメモです。 Memoizationは、同じ入力に対する計算を繰り返さない最適化です。代わりに、以前の結果が返される必要があります。 GCC pure属性は、このようにして関数を機能させることはありません。これを実装する必要があります。

+0

わかりました。私は用語を知らなかった - 記憶、私はそれをキャッシングと呼んでいた、それは私が実装したものです。私はちょうど他の方法があることを望んだ。 – qrdl

+0

@ qrdlでは、memoizationは非常に特殊なキャッシングの形式です。可能な限り専門用語を使用することは避けます。なぜなら、常に会話に価値を加えるとは思わないからです。この場合、単語を知ることは価値のあるものになります。メモライブラリと記事がたくさんあるからです。それは楽しい話題です。 – JaredPar

+0

ありがとう、私はライブラリコードを書くのではなく、最初から暗記コードを書くことにしました。 – qrdl

2

私は、何度も呼び出される高価な関数を持っていますが、パラメータには可能な値のセットが非常に限られています。

静的定数マップを使用しないでください(引数はキーを生成するためにハッシュされる可能性があります)。

+0

戻り値はプログラム実行中に変更されないが、実行間で変更される可能性のあるデータベースに依存するため、可能なすべてのパラメータ値に対して少なくとも1回は関数を呼び出す必要があります。 – qrdl

+0

Hm。データが1回の実行で変更されない限り、マップを作成することはできます。ルックアップテーブルは常に甘いです。 – dirkgently

+0

それは私がやっていることで、私はキャッシングと呼んでいます。 JaredParはそれが暗記と呼ばれると言った。 – qrdl

1

これはテンプレート関数で解決できるように聞こえます。既知のパラメータと戻り値がコンパイル時にわかっている場合は、すべての可能なパラメータに対して関数のテンプレートインスタンスを生成できます。基本的には、可能なパラメータごとに異なる関数のインスタンスを呼び出すことになります。すでに実装している静的キャッシュよりも簡単なことはわかりませんが、検討する価値があるかもしれません。

template metaprogrammingをご覧ください。この概念は、JaredParによって提案された「メモ」と同様であり、階乗関数の同じ導入例を使用しても同じです。これらの種類のテンプレートは、コンパイル時のメモの実装であると言うのが適切かもしれません。

+0

パラメータと戻り値はコンパイル時には分かりません。しかし、あなたはテンプレート機能について詳しく教えていただけますか?私はこのアプローチについて聞いたことがありません。 – qrdl

+0

私は上記のリファレンスを追加しました。あなたの問題に適した例を書くのに十分な実践的な経験はありません。あなたの現在の問題には役に立たないかもしれませんが、C++テンプレートエンジンで何ができるのかを調べることは確かに面白いです。 – veefu

+0

私はちょうどあなたが厳密なC言語で働いているかもしれないことに気づいた。この場合、気を散らすための私の謝罪。 – veefu

1

私は古いスレッドを再開したいが、ここでは特に不快なコメントがあったいけない:

「テンプレートではなく、同じタイプの異なる値よりも、さまざまな種類を扱うためのものである」

今、取ります

template<int n> struct Factorial { 
    static const int value = n * Factorial<n-1>::value; 
}; 

template<> struct Factorial<0> { 
    static const int value = 1; 
}; 

テンプレートパラメータは、typenameではなく整数です。

関連する問題