円舞君が最近Cを勉強してるらしい。で、3つの値の最大値を返す関数*1はこんな感じかと聞いてきた
int max(int a,int b,int c){
if(a>b){
if(a>c){
return a;
}else{
return c;
}
}else if(b>c){
return b;
}else{
return c;
}
}
ので1行で書いてみた。
int max(int a,int b,int c){
return (a>b)?(a>c)?a:c:(b>c)?b:c;
}
じゃあ実際どれくらい違うのかと思ったのでgcc -Sでアセンブリコードを見てみた。
.globl _ifmax
.def _ifmax; .scl 2; .type 32; .endef
_ifmax:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
jle L2
movl 8(%ebp), %eax
cmpl 16(%ebp), %eax
jle L3
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
jmp L1
L3:
movl 16(%ebp), %eax
movl %eax, -4(%ebp)
jmp L1
L2:
movl 12(%ebp), %eax
cmpl 16(%ebp), %eax
jle L6
movl 12(%ebp), %eax
movl %eax, -4(%ebp)
jmp L1
L6:
movl 16(%ebp), %eax
movl %eax, -4(%ebp)
L1:
movl -4(%ebp), %eax
leave
ret
.globl _sanmax
.def _sanmax; .scl 2; .type 32; .endef
_sanmax:
pushl %ebp
movl %esp, %ebp
subl $12, %esp
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
jle L9
movl 8(%ebp), %eax
movl %eax, -8(%ebp)
movl 16(%ebp), %eax
movl %eax, -4(%ebp)
movl -8(%ebp), %eax
cmpl %eax, -4(%ebp)
jge L10
movl -8(%ebp), %eax
movl %eax, -4(%ebp)
jmp L10
L9:
movl 12(%ebp), %eax
movl %eax, -12(%ebp)
movl 16(%ebp), %eax
movl %eax, -4(%ebp)
movl -12(%ebp), %eax
cmpl %eax, -4(%ebp)
jge L10
movl -12(%ebp), %eax
movl %eax, -4(%ebp)
L10:
movl -4(%ebp), %eax
leave
ret
おお、どっちも同じ行数だ。-Oとかやると両方とも分量は減るが、最適化のレベルを上げてみても全く同じになるわけでもないらしい。
ランキング→ 1 2 3
*1:実際はもうちょっと複雑