Golang:使切片性能

为什么这些基准测试结果如此不同?


func Benchmark1(b *testing.B) {

    for n := 0; n < b.N; n++ {

        _ = make([]byte, 8)

    }

}


func Benchmark2(b *testing.B) {

    length := 1

    for n := 0; n < b.N; n++ {

        _ = make([]byte, 7+length)

    }

}

基准测试结果:


Benchmark1-8                    500000000            3.37 ns/op

Benchmark2-8                    30000000            50.6 ns/op


陪伴而非守候
浏览 163回答 1
1回答

手掌心

常量表达式8在编译时计算。在make分配上够程堆栈(便宜)。变量表达式7 + length在运行时计算。在make被分配于程序堆中(昂贵的)。如果make堆栈分配的大小太大(例如, constant(64*1024)和 variable (64*1024-1)+length),则两种分配都在堆上进行,并且基准测试时间相同。$ go tool compile -m a_test.goa_test.go:5: Benchmark1 b does not escapea_test.go:7: Benchmark1 make([]byte, 8) does not escapea_test.go:14: make([]byte, 7 + length) escapes to heapa_test.go:11: Benchmark2 b does not escape$&nbsp;a_test.go:package aimport "testing"func Benchmark1(b *testing.B) {&nbsp; &nbsp; for n := 0; n < b.N; n++ {&nbsp; &nbsp; &nbsp; &nbsp; _ = make([]byte, 8)&nbsp; &nbsp; }}func Benchmark2(b *testing.B) {&nbsp; &nbsp; length := 1&nbsp; &nbsp; for n := 0; n < b.N; n++ {&nbsp; &nbsp; &nbsp; &nbsp; _ = make([]byte, 7+length)&nbsp; &nbsp; }}Go 伪汇编程序:$ go tool compile -S a_test.go基准 1:"".Benchmark1 t=1 size=112 value=0 args=0x8 locals=0x20&nbsp; &nbsp; 0x0000 00000 (a_test.go:5)&nbsp; TEXT&nbsp; &nbsp; "".Benchmark1(SB), $32-8&nbsp; &nbsp; 0x0000 00000 (a_test.go:5)&nbsp; SUBQ&nbsp; &nbsp; $32, SP&nbsp; &nbsp; 0x0004 00004 (a_test.go:5)&nbsp; MOVQ&nbsp; &nbsp; "".b+40(FP), CX&nbsp; &nbsp; 0x0009 00009 (a_test.go:5)&nbsp; FUNCDATA&nbsp; &nbsp; $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)&nbsp; &nbsp; 0x0009 00009 (a_test.go:5)&nbsp; FUNCDATA&nbsp; &nbsp; $1, gclocals·790e5cc5051fc0affc980ade09e929ec(SB)&nbsp; &nbsp; 0x0009 00009 (a_test.go:6)&nbsp; MOVQ&nbsp; &nbsp; $0, AX&nbsp; &nbsp; 0x000b 00011 (a_test.go:6)&nbsp; NOP&nbsp; &nbsp; 0x000b 00011 (a_test.go:6)&nbsp; MOVQ&nbsp; &nbsp; 112(CX), BX&nbsp; &nbsp; 0x000f 00015 (a_test.go:6)&nbsp; CMPQ&nbsp; &nbsp; BX, AX&nbsp; &nbsp; 0x0012 00018 (a_test.go:6)&nbsp; JLE $0, 98&nbsp; &nbsp; 0x0014 00020 (a_test.go:7)&nbsp; MOVQ&nbsp; &nbsp; $0, BX&nbsp; &nbsp; 0x0016 00022 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001(SP)&nbsp; &nbsp; 0x0019 00025 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+1(SP)&nbsp; &nbsp; 0x001d 00029 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+2(SP)&nbsp; &nbsp; 0x0021 00033 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+3(SP)&nbsp; &nbsp; 0x0025 00037 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+4(SP)&nbsp; &nbsp; 0x0029 00041 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+5(SP)&nbsp; &nbsp; 0x002d 00045 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+6(SP)&nbsp; &nbsp; 0x0031 00049 (a_test.go:7)&nbsp; MOVB&nbsp; &nbsp; BL, "".autotmp_0001+7(SP)&nbsp; &nbsp; 0x0035 00053 (a_test.go:7)&nbsp; LEAQ&nbsp; &nbsp; "".autotmp_0001(SP), BX&nbsp; &nbsp; 0x0039 00057 (a_test.go:7)&nbsp; CMPQ&nbsp; &nbsp; BX, $0&nbsp; &nbsp; 0x003d 00061 (a_test.go:7)&nbsp; JEQ $1, 103&nbsp; &nbsp; 0x003f 00063 (a_test.go:7)&nbsp; MOVQ&nbsp; &nbsp; $8, "".autotmp_0002+16(SP)&nbsp; &nbsp; 0x0048 00072 (a_test.go:7)&nbsp; MOVQ&nbsp; &nbsp; $8, "".autotmp_0002+24(SP)&nbsp; &nbsp; 0x0051 00081 (a_test.go:7)&nbsp; MOVQ&nbsp; &nbsp; BX, "".autotmp_0002+8(SP)&nbsp; &nbsp; 0x0056 00086 (a_test.go:6)&nbsp; INCQ&nbsp; &nbsp; AX&nbsp; &nbsp; 0x0059 00089 (a_test.go:6)&nbsp; NOP&nbsp; &nbsp; 0x0059 00089 (a_test.go:6)&nbsp; MOVQ&nbsp; &nbsp; 112(CX), BX&nbsp; &nbsp; 0x005d 00093 (a_test.go:6)&nbsp; CMPQ&nbsp; &nbsp; BX, AX&nbsp; &nbsp; 0x0060 00096 (a_test.go:6)&nbsp; JGT $0, 20&nbsp; &nbsp; 0x0062 00098 (a_test.go:9)&nbsp; ADDQ&nbsp; &nbsp; $32, SP&nbsp; &nbsp; 0x0066 00102 (a_test.go:9)&nbsp; RET&nbsp; &nbsp; 0x0067 00103 (a_test.go:7)&nbsp; MOVL&nbsp; &nbsp; AX, (BX)&nbsp; &nbsp; 0x0069 00105 (a_test.go:7)&nbsp; JMP 63Benchmark2:"".Benchmark2 t=1 size=144 value=0 args=0x8 locals=0x58&nbsp; &nbsp; 0x0000 00000 (a_test.go:11) TEXT&nbsp; &nbsp; "".Benchmark2(SB), $88-8&nbsp; &nbsp; 0x0000 00000 (a_test.go:11) MOVQ&nbsp; &nbsp; (TLS), CX&nbsp; &nbsp; 0x0009 00009 (a_test.go:11) CMPQ&nbsp; &nbsp; SP, 16(CX)&nbsp; &nbsp; 0x000d 00013 (a_test.go:11) JLS 129&nbsp; &nbsp; 0x000f 00015 (a_test.go:11) SUBQ&nbsp; &nbsp; $88, SP&nbsp; &nbsp; 0x0013 00019 (a_test.go:11) FUNCDATA&nbsp; &nbsp; $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)&nbsp; &nbsp; 0x0013 00019 (a_test.go:11) FUNCDATA&nbsp; &nbsp; $1, gclocals·790e5cc5051fc0affc980ade09e929ec(SB)&nbsp; &nbsp; 0x0013 00019 (a_test.go:12) MOVQ&nbsp; &nbsp; $1, "".length+56(SP)&nbsp; &nbsp; 0x001c 00028 (a_test.go:13) MOVQ&nbsp; &nbsp; $0, AX&nbsp; &nbsp; 0x001e 00030 (a_test.go:13) MOVQ&nbsp; &nbsp; "".b+96(FP), BP&nbsp; &nbsp; 0x0023 00035 (a_test.go:13) NOP&nbsp; &nbsp; 0x0023 00035 (a_test.go:13) MOVQ&nbsp; &nbsp; 112(BP), BX&nbsp; &nbsp; 0x0027 00039 (a_test.go:13) MOVQ&nbsp; &nbsp; AX, "".n+48(SP)&nbsp; &nbsp; 0x002c 00044 (a_test.go:13) CMPQ&nbsp; &nbsp; BX, AX&nbsp; &nbsp; 0x002f 00047 (a_test.go:13) JLE $0, 124&nbsp; &nbsp; 0x0031 00049 (a_test.go:14) MOVQ&nbsp; &nbsp; "".length+56(SP), AX&nbsp; &nbsp; 0x0036 00054 (a_test.go:14) ADDQ&nbsp; &nbsp; $7, AX&nbsp; &nbsp; 0x003a 00058 (a_test.go:14) LEAQ&nbsp; &nbsp; type.[]uint8(SB), BX&nbsp; &nbsp; 0x0041 00065 (a_test.go:14) MOVQ&nbsp; &nbsp; BX, (SP)&nbsp; &nbsp; 0x0045 00069 (a_test.go:14) MOVQ&nbsp; &nbsp; AX, 8(SP)&nbsp; &nbsp; 0x004a 00074 (a_test.go:14) MOVQ&nbsp; &nbsp; AX, 16(SP)&nbsp; &nbsp; 0x004f 00079 (a_test.go:14) PCDATA&nbsp; $0, $0&nbsp; &nbsp; 0x004f 00079 (a_test.go:14) CALL&nbsp; &nbsp; runtime.makeslice(SB)&nbsp; &nbsp; 0x0054 00084 (a_test.go:14) MOVQ&nbsp; &nbsp; 24(SP), BX&nbsp; &nbsp; 0x0059 00089 (a_test.go:14) MOVQ&nbsp; &nbsp; BX, "".autotmp_0005+64(SP)&nbsp; &nbsp; 0x005e 00094 (a_test.go:14) MOVQ&nbsp; &nbsp; 32(SP), BX&nbsp; &nbsp; 0x0063 00099 (a_test.go:14) MOVQ&nbsp; &nbsp; BX, "".autotmp_0005+72(SP)&nbsp; &nbsp; 0x0068 00104 (a_test.go:14) MOVQ&nbsp; &nbsp; 40(SP), BX&nbsp; &nbsp; 0x006d 00109 (a_test.go:14) MOVQ&nbsp; &nbsp; BX, "".autotmp_0005+80(SP)&nbsp; &nbsp; 0x0072 00114 (a_test.go:13) MOVQ&nbsp; &nbsp; "".n+48(SP), AX&nbsp; &nbsp; 0x0077 00119 (a_test.go:13) INCQ&nbsp; &nbsp; AX&nbsp; &nbsp; 0x007a 00122 (a_test.go:13) NOP&nbsp; &nbsp; 0x007a 00122 (a_test.go:13) JMP 30&nbsp; &nbsp; 0x007c 00124 (a_test.go:16) ADDQ&nbsp; &nbsp; $88, SP&nbsp; &nbsp; 0x0080 00128 (a_test.go:16) RET&nbsp; &nbsp; 0x0081 00129 (a_test.go:11) CALL&nbsp; &nbsp; runtime.morestack_noctxt(SB)&nbsp; &nbsp; 0x0086 00134 (a_test.go:11) JMP 0
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go