、単にコンパイラにそれを任せます。私はgccが "狂った" -O3
レベルで出力するコードを見てきました。これらの最適化エンジンを書いた人がエイリアンであるか、実質的に遠い将来の時間であることが証明されています。
私はまだregister
またはinline
が私のコードの性能に大きな違いをもたらしたという状況を見ていません。それはそれがでないことを意味しません、コンパイラの作家は、プロセッサからのパフォーマンスの最後のオンスを抽出することになると私たち単なる人間よりもはるかに多くのトリックを知っていることを意味します。
最適化が行われる限りは、実際の問題がある場合にのみ行う必要があります。つまり、コードをプロファイリングしてボトルネックを発見することですが、より重要なことは、コンテキストが遅いとは見なされない操作を最適化しないことです。ワンショット操作が10分の1秒か100分の1かどうかは、ユーザーにはゼロになります。
そして、時には、読みやすくするための最適化はさておき、これはあなたのためだけの気の利いたトリックのgccいれるとして、あなたは
:-)できる最善の一つです。これは、(-O3
時)にコンパイル
static int fact (unsigned int n) {
if (n == 0) return 1;
return n * fact (n-1);
}
int main (void) {
return fact (6);
}
:階乗を計算し、それを返すことになって、次のコードを考えてみましょうそうですねそれ
main: pushl %ebp ; stack frame setup.
movl $720, %eax ; just load 720 (6!) into eax.
movl %esp, %ebp ; stack frame
popl %ebp ; tear-down.
ret ; and return.
、gccがちょうどコンパイル時にそれをすべてうまくいきます-O0
(ナイーブ)バージョンと
int main (void) { return 720; }
コントラストこの:との同等に全部をオン
main: pushl %ebp ; stack
movl %esp, %ebp ; frame
andl $-16, %esp ; set
subl $16, %esp ; up.
movl $6, (%esp) ; pass 6 as parameter.
call fact ; call factorial function.
leave ; stack frame tear down.
ret ; and exit.
fact: pushl %ebp ; stack
movl %esp, %ebp ; frame
subl $24, %esp ; set up.
cmpl $0, 8(%ebp) ; passed param zero?
jne .L2 ; no, keep going.
movl $1, %eax ; yes, set return to 1.
jmp .L3 ; goto return bit.
.L2: movl 8(%ebp), %eax ; get parameter.
subl $1, %eax ; decrement.
movl %eax, (%esp) ; pass that value to next level down.
call fact ; call factorial function.
imull 8(%ebp), %eax ; multiply return value by passed param.
.L3: leave ; stack frame tear down.
ret ; and exit.
コンパイラも人です! :-)あなたのコードが読んで理解しやすいなら、彼らはあなたの意図を見て、そのコードを生成します。あなたが以前に見たことのない "スマートな技"を行うなら、あなたの大学生もコンパイラもそのことで何をするかを知ることはできません。 –