私はいくつかの単純な機能を持っています
#define JacobiLog(x1,x2) ((x1>x2)?x1:x2)+log(1+exp(-fabs(x1-x2)))
実装する方が良いもの(コード、コンパイル、メモリ...)-上記のように定義するか、単純な関数を書く
double JacobiLog(double x1,double x2)
{
return ((x1>x2) ? x1 : x2) + log(1+exp(-fabs(x1-x2)));
}
私はいくつかの単純な機能を持っています
#define JacobiLog(x1,x2) ((x1>x2)?x1:x2)+log(1+exp(-fabs(x1-x2)))
実装する方が良いもの(コード、コンパイル、メモリ...)-上記のように定義するか、単純な関数を書く
double JacobiLog(double x1,double x2)
{
return ((x1>x2) ? x1 : x2) + log(1+exp(-fabs(x1-x2)));
}
コンパイラはおそらく自動的に関数をinlineとして設定します。定義ではなく、それを使用する必要があります。
また、定義を次のように使用する場合の予期しない動作を回避します。
double num = JacobiLog(x++, y++);
コード置換の問題を想像させてください...
define
おそらく少し速くなる可能性がありますが、ほとんどの場合、コンパイラはとにかく関数をインライン化します(またはインラインとしてマークできます)。それらは同じになります。しかし、読みやすく、デバッグしやすいため、機能は優れています。
優れたコンパイラを前提として、関数はより優れています。
関数では、コードがインライン化されているかどうかはコンパイラに任されています (関数の定義が、それを使用するすべての人にアクセス可能であると仮定します。たとえば、inline
C++ のヘッダーで宣言された関数であるか、単にすべてのユーザーが同じ翻訳単位にある単純な関数)。マクロを使用すると、常にインライン化されますが、必ずしも高速ではありません。コードが肥大化し、キャッシュ ミスやページ フォールトが増える可能性があるためです。
言うまでもなく、マクロは読みにくく、さらに悪いことにデバッグも困難です。
'define' の方が高速ですが (関数呼び出しを防止するため)、コンパイラは関数を最適化およびインライン化して、高速にすることができます。
C++ 環境にいる場合は、常にテンプレートと関数を使用する必要があります。これにより、プログラムが読みやすくなり、型エラーが防止されます。
C では、タイプが指定されていないため、マクロが役立ちます (以下の例を参照)。
/* Will work with int, long, double, short, etc. */
#HIGHER(VAL1, VAL2) ((VAL1) > (VAL2) ? (VAL1) : (VAL2))
マイクロ最適化です。組み込みプログラミングを行っていて、すべての命令が重要でない限り、関数を使用してください。log
関数を呼び出すオーバーヘッドよりも約 100 倍遅い可能性があることは言うまでもありません。したがって、プログラムが主にこの関数の呼び出しで構成されている場合、約 1% の節約しかできません。[1]プログラムが重要な他のことを開始すると、この節約は基本的に目立たなくなります。
コンパイラは、可能な限り自由に関数をインライン化できるため、2 つが同一になります。ただし、コンパイラに強制することはできません。C++ にはキーワードがありますが、inline
これは単なるヒントであり、コンパイラは自由に無視できます。
2 つの違いについては、こちらを参照してください (これはインライン関数と非インライン関数をカバーしていますが、前述のように、インライン関数は本質的に#define
's と同じです)。リンクの基本的な結論は「場合による」です。
また、動作上、 a#define
と a 関数は 100% 同等ではないことに注意してください。
[1]: 図は主に構成されています。正確な結果が必要な場合は、ベンチマークを行ってください。