【golang代码反编译研究】switch 中的常量有助于生成跳转表代码

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


先说结论:一些比较小的循环,可以用 switch + 常量来展开,可以提升性能。因为编译器会为 switch 建立代码段的跳转表,从而不需要很多比较指令。

例如:

for i:= range s{
   if s[i]=='\n'{
       printf("found new line\n")
       return
   }
}

已知:字符串 s 最多 4 个字符。
代码可以优化如下:

switch len(s){
case 0:
   return;
case 1:
   if s[0]=='\n'{/*do something*/}
case 2:
  if s[0]=='\n' || s[1]=='\n'  {/*do something*/}
case 3:
   if s[0]=='\n' || s[1]=='\n'  || s[2]=='\n'{/*do something*/}
case 4:
   if s[0]=='\n' || s[1]=='\n'  || s[2]=='\n'  || s[3]=='\n'{/*do something*/}
default:
   panic("")
}

大量常量 + 代码展开,有助于提升性能。

下面是一个反汇编的例子:

package is_sorted

func switchTest(a int) int {
	switch a {
	case 1:
		return 100
	case 2:
		return 103
	case 3:
		return 205
	case 4:
		return 309
	case 5:
		return 413
	case 6:
		return 517
	case 7:
		return 621
	case 8:
		return 725
	case 9:
		return 829
	default:
		return 933
	}
}

对应的汇编代码如下:

        TEXT    command-line-arguments.switchTest(SB), NOSPLIT|NOFRAME|ABIInternal, $0-8
        FUNCDATA        $0, gclocals·FzY36IO2mY0y4dZ1+Izd/w==(SB)
        FUNCDATA        $1, gclocals·FzY36IO2mY0y4dZ1+Izd/w==(SB)
        FUNCDATA        $5, command-line-arguments.switchTest.arginfo1(SB)
        FUNCDATA        $6, command-line-arguments.switchTest.argliveinfo(SB)
        PCDATA  $3, $1
        LEAQ    -1(AX), CX
        CMPQ    CX, $8
        JHI     command-line-arguments_switchTest_pc75
        LEAQ    command-line-arguments.switchTest.jump3(SB), AX
        JMP     (AX)(CX*8)
        MOVL    $100, AX
        RET
        MOVL    $103, AX
        NOP
        RET
        MOVL    $205, AX
        RET
        MOVL    $309, AX
        RET
        MOVL    $413, AX
        RET
        MOVL    $517, AX
        RET
        MOVL    $621, AX
        RET
        MOVL    $725, AX
        RET
        MOVL    $829, AX
        RET
command-line-arguments_switchTest_pc75:
        MOVL    $933, AX
        RET

command-line-arguments.switchTest.jump3(SB) 这里是一个编译器生成的跳转表。

以上代码在 https://godbolt.org/ 网站生成,非常方便。

posted on 2025-06-06 18:35  ahfuzhang  阅读(52)  评论(0)    收藏  举报