searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Golang深入浅出——泛型实现

2023-10-27 08:13:10
5
0

泛型

泛型是程序设计语言的一种范式或抽象,实现对算法的一种抽象,避免不同数据结构在实现相同算法时重复编码问题,允许在算法实例化时指定算法元素的类型。

golang在1.18实现了对泛型的支持。

生效阶段

泛型作用在编译阶段,编译器会根据泛型的定义和具体调用场景,进行实例化实现;

性能开销

泛型会产生一定的性能开销,泛型算法逻辑越简单性能影响越明显(测试案例:1000000000次a+b求和,原生代码耗时300ms左右,泛型代码耗时1.5s,开销是原生代码的5倍左右),函数复杂时性能开销接近(测试案例:1000000000次fmt.Sprintf操作,原生代码耗时,泛型代码耗时2m8.14s)。

实现原理

编译器在编译阶段,会根据程序对泛型调用场景,生成对应类型的实例化函数,通过CALL调用具体实例化后的函数;

示例:

// 泛型代码
func addT[T int|int64|floag64](a ,b T) T{
    return a+b
}

// 原生代码
func addI(a, b int) int{
    return a+b
}

func addF(a, b float64) float64{
    return a+b
}

func addI64(a, b int64) int64{
    return a+b
}
1)泛型实例化
1.1)对应addT[int](1, 2)调用,实例化函数汇编
main.addT[go.shape.int_0] STEXT dupok nosplit size=61 args=0x18 locals=0x10 funcid=0x0 align=0x0
0x0000 00000 (/generic.go:3)TEXTmain.addT[go.shape.int_0](SB), DUPOK|NOSPLIT|ABIInternal, $16-24
0x0000 00000 (/generic.go:3)SUBQ$16, SP
0x0004 00004 (/generic.go:3)MOVQBP, 8(SP)
0x0009 00009 (/generic.go:3)LEAQ8(SP), BP
0x000e 00014 (/generic.go:3)FUNCDATA$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
0x000e 00014 (/generic.go:3)FUNCDATA$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
0x000e 00014 (/generic.go:3)FUNCDATA$5, main.addT[go.shape.int_0].arginfo1(SB)
0x000e 00014 (/generic.go:3)MOVQAX, main..dict+24(SP)
0x0013 00019 (/generic.go:3)MOVQBX, main.a+32(SP)
0x0018 00024 (/generic.go:3)MOVQCX, main.b+40(SP)
0x001d 00029 (/generic.go:3)MOVQ$0, main.~r0(SP)
0x0025 00037 (/generic.go:4)MOVQmain.a+32(SP), AX
0x002a 00042 (/generic.go:4)ADDQmain.b+40(SP), AX
0x002f 00047 (/generic.go:4)MOVQAX, main.~r0(SP)
0x0033 00051 (/generic.go:4)MOVQ8(SP), BP
0x0038 00056 (/generic.go:4)ADDQ$16, SP
0x003c 00060 (/generic.go:4)RET
0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 89  H...H.l$.H.l$.H.
0x0010 44 24 18 48 89 5c 24 20 48 89 4c 24 28 48 c7 04  D$.H.\$ H.L$(H..
0x0020 24 00 00 00 00 48 8b 44 24 20 48 03 44 24 28 48  $....H.D$ H.D$(H
0x0030 89 04 24 48 8b 6c 24 08 48 83 c4 10 c3           ..$H.l$.H....
1.2)原生代码addI对应汇编
main.addI STEXT nosplit size=56 args=0x10 locals=0x10 funcid=0x0 align=0x0
	0x0000 00000 (/normal_pure.go:3)	TEXT	main.addI(SB), NOSPLIT|ABIInternal, $16-16
	0x0000 00000 (/normal_pure.go:3)	SUBQ	$16, SP
	0x0004 00004 (/normal_pure.go:3)	MOVQ	BP, 8(SP)
	0x0009 00009 (/normal_pure.go:3)	LEAQ	8(SP), BP
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$5, main.addI.arginfo1(SB)
	0x000e 00014 (/normal_pure.go:3)	MOVQ	AX, main.a+24(SP)
	0x0013 00019 (/normal_pure.go:3)	MOVQ	BX, main.b+32(SP)
	0x0018 00024 (/normal_pure.go:3)	MOVQ	$0, main.~r0(SP)
	0x0020 00032 (/normal_pure.go:4)	MOVQ	main.a+24(SP), AX
	0x0025 00037 (/normal_pure.go:4)	ADDQ	main.b+32(SP), AX
	0x002a 00042 (/normal_pure.go:4)	MOVQ	AX, main.~r0(SP)
	0x002e 00046 (/normal_pure.go:4)	MOVQ	8(SP), BP
	0x0033 00051 (/normal_pure.go:4)	ADDQ	$16, SP
	0x0037 00055 (/normal_pure.go:4)	RET
	0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 89  H...H.l$.H.l$.H.
	0x0010 44 24 18 48 89 5c 24 20 48 c7 04 24 00 00 00 00  D$.H.\$ H..$....
	0x0020 48 8b 44 24 18 48 03 44 24 20 48 89 04 24 48 8b  H.D$.H.D$ H..$H.
	0x0030 6c 24 08 48 83 c4 10 c3                          l$.H....

1.3)两者之间的差异,泛型相对原生多了一行:0x000e 00014 (/generic.go:3)MOVQAX, main..dict+24(SP)

 

2)泛型调用

2.1)泛型调用实例化

main.main STEXT size=87 args=0x0 locals=0x20 funcid=0x0 align=0x0
	0x0000 00000 (/generic.go:7)	TEXT	main.main(SB), ABIInternal, $32-0
	0x0000 00000 (/generic.go:7)	CMPQ	SP, 16(R14)
	0x0004 00004 (/generic.go:7)	PCDATA	$0, $-2
	0x0004 00004 (/generic.go:7)	JLS	80
	0x0006 00006 (/generic.go:7)	PCDATA	$0, $-1
	0x0006 00006 (/generic.go:7)	SUBQ	$32, SP
	0x000a 00010 (/generic.go:7)	MOVQ	BP, 24(SP)
	0x000f 00015 (/generic.go:7)	LEAQ	24(SP), BP
	0x0014 00020 (/generic.go:7)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x0014 00020 (/generic.go:7)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x0014 00020 (/generic.go:8)	LEAQ	main..dict.addT[int](SB), AX
	0x001b 00027 (/generic.go:8)	MOVL	$1, BX
	0x0020 00032 (/generic.go:8)	MOVL	$2, CX
	0x0025 00037 (/generic.go:8)	PCDATA	$1, $0
	0x0025 00037 (/generic.go:8)	CALL	main.addT[go.shape.int_0](SB)
	0x002a 00042 (/generic.go:10)	LEAQ	main..dict.addT[float64](SB), AX
	0x0031 00049 (/generic.go:10)	MOVSD	$f64.3ff0000000000000(SB), X0
	0x0039 00057 (/generic.go:10)	MOVSD	$f64.4000000000000000(SB), X1
	0x0041 00065 (/generic.go:10)	CALL	main.addT[go.shape.float64_0](SB)
	0x0046 00070 (/generic.go:11)	MOVQ	24(SP), BP
	0x004b 00075 (/generic.go:11)	ADDQ	$32, SP
	0x004f 00079 (/generic.go:11)	RET
	0x0050 00080 (/generic.go:11)	NOP
	0x0050 00080 (/generic.go:7)	PCDATA	$1, $-1
	0x0050 00080 (/generic.go:7)	PCDATA	$0, $-2
	0x0050 00080 (/generic.go:7)	CALL	runtime.morestack_noctxt(SB)
	0x0055 00085 (/generic.go:7)	PCDATA	$0, $-1
	0x0055 00085 (/generic.go:7)	JMP	0
	0x0000 49 3b 66 10 76 4a 48 83 ec 20 48 89 6c 24 18 48  I;f.vJH.. H.l$.H
	0x0010 8d 6c 24 18 48 8d 05 00 00 00 00 bb 01 00 00 00  .l$.H...........
	0x0020 b9 02 00 00 00 e8 00 00 00 00 48 8d 05 00 00 00  ..........H.....
	0x0030 00 f2 0f 10 05 00 00 00 00 f2 0f 10 0d 00 00 00  ................
	0x0040 00 e8 00 00 00 00 48 8b 6c 24 18 48 83 c4 20 c3  ......H.l$.H.. .
	0x0050 e8 00 00 00 00 eb a9                             .......
	rel 23+4 t=14 main..dict.addT[int]+0
	rel 38+4 t=7 main.addT[go.shape.int_0]+0
	rel 45+4 t=14 main..dict.addT[float64]+0
	rel 53+4 t=14 $f64.3ff0000000000000+0
	rel 61+4 t=14 $f64.4000000000000000+0
	rel 66+4 t=7 main.addT[go.shape.float64_0]+0
	rel 81+4 t=7 runtime.morestack_noctxt+0

 2.2)原生代码调用实例化

main.main STEXT nosplit size=103 args=0x0 locals=0x38 funcid=0x0 align=0x0
	0x0000 00000 (/normal_pure.go:11)	TEXT	main.main(SB), NOSPLIT|ABIInternal, $56-0
	0x0000 00000 (/normal_pure.go:11)	SUBQ	$56, SP
	0x0004 00004 (/normal_pure.go:11)	MOVQ	BP, 48(SP)
	0x0009 00009 (/normal_pure.go:11)	LEAQ	48(SP), BP
	0x000e 00014 (/normal_pure.go:11)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:11)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:12)	MOVQ	$1, main.a+40(SP)
	0x0017 00023 (/normal_pure.go:12)	MOVQ	$2, main.b+24(SP)
	0x0020 00032 (<unknown line number>)	NOP
	0x0020 00032 (/normal_pure.go:4)	MOVQ	main.a+40(SP), AX
	0x0025 00037 (/normal_pure.go:4)	ADDQ	$2, AX
	0x0029 00041 (/normal_pure.go:12)	MOVQ	AX, main.~R0+8(SP)
	0x002e 00046 (/normal_pure.go:12)	JMP	48
	0x0030 00048 (/normal_pure.go:14)	MOVSD	$f64.3ff0000000000000(SB), X0
	0x0038 00056 (/normal_pure.go:14)	MOVSD	X0, main.a+32(SP)
	0x003e 00062 (/normal_pure.go:14)	MOVSD	$f64.4000000000000000(SB), X0
	0x0046 00070 (/normal_pure.go:14)	MOVSD	X0, main.b+16(SP)
	0x004c 00076 (<unknown line number>)	NOP
	0x004c 00076 (/normal_pure.go:8)	MOVSD	main.a+32(SP), X1
	0x0052 00082 (/normal_pure.go:8)	ADDSD	X0, X1
	0x0056 00086 (/normal_pure.go:14)	MOVSD	X1, main.~R0(SP)
	0x005b 00091 (/normal_pure.go:14)	JMP	93
	0x005d 00093 (/normal_pure.go:15)	MOVQ	48(SP), BP
	0x0062 00098 (/normal_pure.go:15)	ADDQ	$56, SP
	0x0066 00102 (/normal_pure.go:15)	RET
	0x0000 48 83 ec 38 48 89 6c 24 30 48 8d 6c 24 30 48 c7  H..8H.l$0H.l$0H.
	0x0010 44 24 28 01 00 00 00 48 c7 44 24 18 02 00 00 00  D$(....H.D$.....
	0x0020 48 8b 44 24 28 48 83 c0 02 48 89 44 24 08 eb 00  H.D$(H...H.D$...
	0x0030 f2 0f 10 05 00 00 00 00 f2 0f 11 44 24 20 f2 0f  ...........D$ ..
	0x0040 10 05 00 00 00 00 f2 0f 11 44 24 10 f2 0f 10 4c  .........D$....L
	0x0050 24 20 f2 0f 58 c8 f2 0f 11 0c 24 eb 00 48 8b 6c  $ ..X.....$..H.l
	0x0060 24 30 48 83 c4 38 c3                             $0H..8.
	rel 52+4 t=14 $f64.3ff0000000000000+0
	rel 66+4 t=14 $f64.4000000000000000+0

2.3)两者之间的差异

2.3.1)泛型调用之前,会多做一些判断操作

0x0000 00000 (/generic.go:7)CMPQSP, 16(R14)
0x0004 00004 (/generic.go:7)PCDATA$0, $-2
0x0004 00004 (/generic.go:7)JLS80
0x0006 00006 (/generic.go:7)PCDATA$0, $-1
 
0x0014 00020 (/generic.go:8)LEAQmain..dict.addT[int](SB), AX

2.3.2)泛型调用使用 CALL执行实例化函数执行,原生代码使用JMP跳转到实例化函数执行

0x0025 00037 (/generic.go:8)CALLmain.addT[go.shape.int_0](SB)

 

 

0条评论
0 / 1000
s****n
5文章数
0粉丝数
s****n
5 文章 | 0 粉丝
原创

Golang深入浅出——泛型实现

2023-10-27 08:13:10
5
0

泛型

泛型是程序设计语言的一种范式或抽象,实现对算法的一种抽象,避免不同数据结构在实现相同算法时重复编码问题,允许在算法实例化时指定算法元素的类型。

golang在1.18实现了对泛型的支持。

生效阶段

泛型作用在编译阶段,编译器会根据泛型的定义和具体调用场景,进行实例化实现;

性能开销

泛型会产生一定的性能开销,泛型算法逻辑越简单性能影响越明显(测试案例:1000000000次a+b求和,原生代码耗时300ms左右,泛型代码耗时1.5s,开销是原生代码的5倍左右),函数复杂时性能开销接近(测试案例:1000000000次fmt.Sprintf操作,原生代码耗时,泛型代码耗时2m8.14s)。

实现原理

编译器在编译阶段,会根据程序对泛型调用场景,生成对应类型的实例化函数,通过CALL调用具体实例化后的函数;

示例:

// 泛型代码
func addT[T int|int64|floag64](a ,b T) T{
    return a+b
}

// 原生代码
func addI(a, b int) int{
    return a+b
}

func addF(a, b float64) float64{
    return a+b
}

func addI64(a, b int64) int64{
    return a+b
}
1)泛型实例化
1.1)对应addT[int](1, 2)调用,实例化函数汇编
main.addT[go.shape.int_0] STEXT dupok nosplit size=61 args=0x18 locals=0x10 funcid=0x0 align=0x0
0x0000 00000 (/generic.go:3)TEXTmain.addT[go.shape.int_0](SB), DUPOK|NOSPLIT|ABIInternal, $16-24
0x0000 00000 (/generic.go:3)SUBQ$16, SP
0x0004 00004 (/generic.go:3)MOVQBP, 8(SP)
0x0009 00009 (/generic.go:3)LEAQ8(SP), BP
0x000e 00014 (/generic.go:3)FUNCDATA$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
0x000e 00014 (/generic.go:3)FUNCDATA$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
0x000e 00014 (/generic.go:3)FUNCDATA$5, main.addT[go.shape.int_0].arginfo1(SB)
0x000e 00014 (/generic.go:3)MOVQAX, main..dict+24(SP)
0x0013 00019 (/generic.go:3)MOVQBX, main.a+32(SP)
0x0018 00024 (/generic.go:3)MOVQCX, main.b+40(SP)
0x001d 00029 (/generic.go:3)MOVQ$0, main.~r0(SP)
0x0025 00037 (/generic.go:4)MOVQmain.a+32(SP), AX
0x002a 00042 (/generic.go:4)ADDQmain.b+40(SP), AX
0x002f 00047 (/generic.go:4)MOVQAX, main.~r0(SP)
0x0033 00051 (/generic.go:4)MOVQ8(SP), BP
0x0038 00056 (/generic.go:4)ADDQ$16, SP
0x003c 00060 (/generic.go:4)RET
0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 89  H...H.l$.H.l$.H.
0x0010 44 24 18 48 89 5c 24 20 48 89 4c 24 28 48 c7 04  D$.H.\$ H.L$(H..
0x0020 24 00 00 00 00 48 8b 44 24 20 48 03 44 24 28 48  $....H.D$ H.D$(H
0x0030 89 04 24 48 8b 6c 24 08 48 83 c4 10 c3           ..$H.l$.H....
1.2)原生代码addI对应汇编
main.addI STEXT nosplit size=56 args=0x10 locals=0x10 funcid=0x0 align=0x0
	0x0000 00000 (/normal_pure.go:3)	TEXT	main.addI(SB), NOSPLIT|ABIInternal, $16-16
	0x0000 00000 (/normal_pure.go:3)	SUBQ	$16, SP
	0x0004 00004 (/normal_pure.go:3)	MOVQ	BP, 8(SP)
	0x0009 00009 (/normal_pure.go:3)	LEAQ	8(SP), BP
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:3)	FUNCDATA	$5, main.addI.arginfo1(SB)
	0x000e 00014 (/normal_pure.go:3)	MOVQ	AX, main.a+24(SP)
	0x0013 00019 (/normal_pure.go:3)	MOVQ	BX, main.b+32(SP)
	0x0018 00024 (/normal_pure.go:3)	MOVQ	$0, main.~r0(SP)
	0x0020 00032 (/normal_pure.go:4)	MOVQ	main.a+24(SP), AX
	0x0025 00037 (/normal_pure.go:4)	ADDQ	main.b+32(SP), AX
	0x002a 00042 (/normal_pure.go:4)	MOVQ	AX, main.~r0(SP)
	0x002e 00046 (/normal_pure.go:4)	MOVQ	8(SP), BP
	0x0033 00051 (/normal_pure.go:4)	ADDQ	$16, SP
	0x0037 00055 (/normal_pure.go:4)	RET
	0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 89  H...H.l$.H.l$.H.
	0x0010 44 24 18 48 89 5c 24 20 48 c7 04 24 00 00 00 00  D$.H.\$ H..$....
	0x0020 48 8b 44 24 18 48 03 44 24 20 48 89 04 24 48 8b  H.D$.H.D$ H..$H.
	0x0030 6c 24 08 48 83 c4 10 c3                          l$.H....

1.3)两者之间的差异,泛型相对原生多了一行:0x000e 00014 (/generic.go:3)MOVQAX, main..dict+24(SP)

 

2)泛型调用

2.1)泛型调用实例化

main.main STEXT size=87 args=0x0 locals=0x20 funcid=0x0 align=0x0
	0x0000 00000 (/generic.go:7)	TEXT	main.main(SB), ABIInternal, $32-0
	0x0000 00000 (/generic.go:7)	CMPQ	SP, 16(R14)
	0x0004 00004 (/generic.go:7)	PCDATA	$0, $-2
	0x0004 00004 (/generic.go:7)	JLS	80
	0x0006 00006 (/generic.go:7)	PCDATA	$0, $-1
	0x0006 00006 (/generic.go:7)	SUBQ	$32, SP
	0x000a 00010 (/generic.go:7)	MOVQ	BP, 24(SP)
	0x000f 00015 (/generic.go:7)	LEAQ	24(SP), BP
	0x0014 00020 (/generic.go:7)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x0014 00020 (/generic.go:7)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x0014 00020 (/generic.go:8)	LEAQ	main..dict.addT[int](SB), AX
	0x001b 00027 (/generic.go:8)	MOVL	$1, BX
	0x0020 00032 (/generic.go:8)	MOVL	$2, CX
	0x0025 00037 (/generic.go:8)	PCDATA	$1, $0
	0x0025 00037 (/generic.go:8)	CALL	main.addT[go.shape.int_0](SB)
	0x002a 00042 (/generic.go:10)	LEAQ	main..dict.addT[float64](SB), AX
	0x0031 00049 (/generic.go:10)	MOVSD	$f64.3ff0000000000000(SB), X0
	0x0039 00057 (/generic.go:10)	MOVSD	$f64.4000000000000000(SB), X1
	0x0041 00065 (/generic.go:10)	CALL	main.addT[go.shape.float64_0](SB)
	0x0046 00070 (/generic.go:11)	MOVQ	24(SP), BP
	0x004b 00075 (/generic.go:11)	ADDQ	$32, SP
	0x004f 00079 (/generic.go:11)	RET
	0x0050 00080 (/generic.go:11)	NOP
	0x0050 00080 (/generic.go:7)	PCDATA	$1, $-1
	0x0050 00080 (/generic.go:7)	PCDATA	$0, $-2
	0x0050 00080 (/generic.go:7)	CALL	runtime.morestack_noctxt(SB)
	0x0055 00085 (/generic.go:7)	PCDATA	$0, $-1
	0x0055 00085 (/generic.go:7)	JMP	0
	0x0000 49 3b 66 10 76 4a 48 83 ec 20 48 89 6c 24 18 48  I;f.vJH.. H.l$.H
	0x0010 8d 6c 24 18 48 8d 05 00 00 00 00 bb 01 00 00 00  .l$.H...........
	0x0020 b9 02 00 00 00 e8 00 00 00 00 48 8d 05 00 00 00  ..........H.....
	0x0030 00 f2 0f 10 05 00 00 00 00 f2 0f 10 0d 00 00 00  ................
	0x0040 00 e8 00 00 00 00 48 8b 6c 24 18 48 83 c4 20 c3  ......H.l$.H.. .
	0x0050 e8 00 00 00 00 eb a9                             .......
	rel 23+4 t=14 main..dict.addT[int]+0
	rel 38+4 t=7 main.addT[go.shape.int_0]+0
	rel 45+4 t=14 main..dict.addT[float64]+0
	rel 53+4 t=14 $f64.3ff0000000000000+0
	rel 61+4 t=14 $f64.4000000000000000+0
	rel 66+4 t=7 main.addT[go.shape.float64_0]+0
	rel 81+4 t=7 runtime.morestack_noctxt+0

 2.2)原生代码调用实例化

main.main STEXT nosplit size=103 args=0x0 locals=0x38 funcid=0x0 align=0x0
	0x0000 00000 (/normal_pure.go:11)	TEXT	main.main(SB), NOSPLIT|ABIInternal, $56-0
	0x0000 00000 (/normal_pure.go:11)	SUBQ	$56, SP
	0x0004 00004 (/normal_pure.go:11)	MOVQ	BP, 48(SP)
	0x0009 00009 (/normal_pure.go:11)	LEAQ	48(SP), BP
	0x000e 00014 (/normal_pure.go:11)	FUNCDATA	$0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:11)	FUNCDATA	$1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
	0x000e 00014 (/normal_pure.go:12)	MOVQ	$1, main.a+40(SP)
	0x0017 00023 (/normal_pure.go:12)	MOVQ	$2, main.b+24(SP)
	0x0020 00032 (<unknown line number>)	NOP
	0x0020 00032 (/normal_pure.go:4)	MOVQ	main.a+40(SP), AX
	0x0025 00037 (/normal_pure.go:4)	ADDQ	$2, AX
	0x0029 00041 (/normal_pure.go:12)	MOVQ	AX, main.~R0+8(SP)
	0x002e 00046 (/normal_pure.go:12)	JMP	48
	0x0030 00048 (/normal_pure.go:14)	MOVSD	$f64.3ff0000000000000(SB), X0
	0x0038 00056 (/normal_pure.go:14)	MOVSD	X0, main.a+32(SP)
	0x003e 00062 (/normal_pure.go:14)	MOVSD	$f64.4000000000000000(SB), X0
	0x0046 00070 (/normal_pure.go:14)	MOVSD	X0, main.b+16(SP)
	0x004c 00076 (<unknown line number>)	NOP
	0x004c 00076 (/normal_pure.go:8)	MOVSD	main.a+32(SP), X1
	0x0052 00082 (/normal_pure.go:8)	ADDSD	X0, X1
	0x0056 00086 (/normal_pure.go:14)	MOVSD	X1, main.~R0(SP)
	0x005b 00091 (/normal_pure.go:14)	JMP	93
	0x005d 00093 (/normal_pure.go:15)	MOVQ	48(SP), BP
	0x0062 00098 (/normal_pure.go:15)	ADDQ	$56, SP
	0x0066 00102 (/normal_pure.go:15)	RET
	0x0000 48 83 ec 38 48 89 6c 24 30 48 8d 6c 24 30 48 c7  H..8H.l$0H.l$0H.
	0x0010 44 24 28 01 00 00 00 48 c7 44 24 18 02 00 00 00  D$(....H.D$.....
	0x0020 48 8b 44 24 28 48 83 c0 02 48 89 44 24 08 eb 00  H.D$(H...H.D$...
	0x0030 f2 0f 10 05 00 00 00 00 f2 0f 11 44 24 20 f2 0f  ...........D$ ..
	0x0040 10 05 00 00 00 00 f2 0f 11 44 24 10 f2 0f 10 4c  .........D$....L
	0x0050 24 20 f2 0f 58 c8 f2 0f 11 0c 24 eb 00 48 8b 6c  $ ..X.....$..H.l
	0x0060 24 30 48 83 c4 38 c3                             $0H..8.
	rel 52+4 t=14 $f64.3ff0000000000000+0
	rel 66+4 t=14 $f64.4000000000000000+0

2.3)两者之间的差异

2.3.1)泛型调用之前,会多做一些判断操作

0x0000 00000 (/generic.go:7)CMPQSP, 16(R14)
0x0004 00004 (/generic.go:7)PCDATA$0, $-2
0x0004 00004 (/generic.go:7)JLS80
0x0006 00006 (/generic.go:7)PCDATA$0, $-1
 
0x0014 00020 (/generic.go:8)LEAQmain..dict.addT[int](SB), AX

2.3.2)泛型调用使用 CALL执行实例化函数执行,原生代码使用JMP跳转到实例化函数执行

0x0025 00037 (/generic.go:8)CALLmain.addT[go.shape.int_0](SB)

 

 

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0