草庐IT

Golang : make slice performance

coder 2023-04-30 原文

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

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

最佳答案

常量表达式8 在编译时被计算。 make 分配在 goroutine 堆栈上(便宜)。变量表达式 7 + length 在运行时计算。 make 分配在程序堆上(昂贵)。如果 make 大小对于堆栈分配来说太大(例如,常量 (64*1024) 和变量 (64*1024-1)+length) 那么两个分配都是在堆上进行的,并且基准测试时间是相同的。

$ go tool compile -m a_test.go
a_test.go:5: Benchmark1 b does not escape
a_test.go:7: Benchmark1 make([]byte, 8) does not escape
a_test.go:14: make([]byte, 7 + length) escapes to heap
a_test.go:11: Benchmark2 b does not escape
$ 

a_test.go:

package a

import "testing"

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)
    }
}

去伪汇编:

$ go tool compile -S a_test.go

基准1:

"".Benchmark1 t=1 size=112 value=0 args=0x8 locals=0x20
    0x0000 00000 (a_test.go:5)  TEXT    "".Benchmark1(SB), $32-8
    0x0000 00000 (a_test.go:5)  SUBQ    $32, SP
    0x0004 00004 (a_test.go:5)  MOVQ    "".b+40(FP), CX
    0x0009 00009 (a_test.go:5)  FUNCDATA    $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)
    0x0009 00009 (a_test.go:5)  FUNCDATA    $1, gclocals·790e5cc5051fc0affc980ade09e929ec(SB)
    0x0009 00009 (a_test.go:6)  MOVQ    $0, AX
    0x000b 00011 (a_test.go:6)  NOP
    0x000b 00011 (a_test.go:6)  MOVQ    112(CX), BX
    0x000f 00015 (a_test.go:6)  CMPQ    BX, AX
    0x0012 00018 (a_test.go:6)  JLE $0, 98
    0x0014 00020 (a_test.go:7)  MOVQ    $0, BX
    0x0016 00022 (a_test.go:7)  MOVB    BL, "".autotmp_0001(SP)
    0x0019 00025 (a_test.go:7)  MOVB    BL, "".autotmp_0001+1(SP)
    0x001d 00029 (a_test.go:7)  MOVB    BL, "".autotmp_0001+2(SP)
    0x0021 00033 (a_test.go:7)  MOVB    BL, "".autotmp_0001+3(SP)
    0x0025 00037 (a_test.go:7)  MOVB    BL, "".autotmp_0001+4(SP)
    0x0029 00041 (a_test.go:7)  MOVB    BL, "".autotmp_0001+5(SP)
    0x002d 00045 (a_test.go:7)  MOVB    BL, "".autotmp_0001+6(SP)
    0x0031 00049 (a_test.go:7)  MOVB    BL, "".autotmp_0001+7(SP)
    0x0035 00053 (a_test.go:7)  LEAQ    "".autotmp_0001(SP), BX
    0x0039 00057 (a_test.go:7)  CMPQ    BX, $0
    0x003d 00061 (a_test.go:7)  JEQ $1, 103
    0x003f 00063 (a_test.go:7)  MOVQ    $8, "".autotmp_0002+16(SP)
    0x0048 00072 (a_test.go:7)  MOVQ    $8, "".autotmp_0002+24(SP)
    0x0051 00081 (a_test.go:7)  MOVQ    BX, "".autotmp_0002+8(SP)
    0x0056 00086 (a_test.go:6)  INCQ    AX
    0x0059 00089 (a_test.go:6)  NOP
    0x0059 00089 (a_test.go:6)  MOVQ    112(CX), BX
    0x005d 00093 (a_test.go:6)  CMPQ    BX, AX
    0x0060 00096 (a_test.go:6)  JGT $0, 20
    0x0062 00098 (a_test.go:9)  ADDQ    $32, SP
    0x0066 00102 (a_test.go:9)  RET
    0x0067 00103 (a_test.go:7)  MOVL    AX, (BX)
    0x0069 00105 (a_test.go:7)  JMP 63

Benchmark2:

"".Benchmark2 t=1 size=144 value=0 args=0x8 locals=0x58
    0x0000 00000 (a_test.go:11) TEXT    "".Benchmark2(SB), $88-8
    0x0000 00000 (a_test.go:11) MOVQ    (TLS), CX
    0x0009 00009 (a_test.go:11) CMPQ    SP, 16(CX)
    0x000d 00013 (a_test.go:11) JLS 129
    0x000f 00015 (a_test.go:11) SUBQ    $88, SP
    0x0013 00019 (a_test.go:11) FUNCDATA    $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)
    0x0013 00019 (a_test.go:11) FUNCDATA    $1, gclocals·790e5cc5051fc0affc980ade09e929ec(SB)
    0x0013 00019 (a_test.go:12) MOVQ    $1, "".length+56(SP)
    0x001c 00028 (a_test.go:13) MOVQ    $0, AX
    0x001e 00030 (a_test.go:13) MOVQ    "".b+96(FP), BP
    0x0023 00035 (a_test.go:13) NOP
    0x0023 00035 (a_test.go:13) MOVQ    112(BP), BX
    0x0027 00039 (a_test.go:13) MOVQ    AX, "".n+48(SP)
    0x002c 00044 (a_test.go:13) CMPQ    BX, AX
    0x002f 00047 (a_test.go:13) JLE $0, 124
    0x0031 00049 (a_test.go:14) MOVQ    "".length+56(SP), AX
    0x0036 00054 (a_test.go:14) ADDQ    $7, AX
    0x003a 00058 (a_test.go:14) LEAQ    type.[]uint8(SB), BX
    0x0041 00065 (a_test.go:14) MOVQ    BX, (SP)
    0x0045 00069 (a_test.go:14) MOVQ    AX, 8(SP)
    0x004a 00074 (a_test.go:14) MOVQ    AX, 16(SP)
    0x004f 00079 (a_test.go:14) PCDATA  $0, $0
    0x004f 00079 (a_test.go:14) CALL    runtime.makeslice(SB)
    0x0054 00084 (a_test.go:14) MOVQ    24(SP), BX
    0x0059 00089 (a_test.go:14) MOVQ    BX, "".autotmp_0005+64(SP)
    0x005e 00094 (a_test.go:14) MOVQ    32(SP), BX
    0x0063 00099 (a_test.go:14) MOVQ    BX, "".autotmp_0005+72(SP)
    0x0068 00104 (a_test.go:14) MOVQ    40(SP), BX
    0x006d 00109 (a_test.go:14) MOVQ    BX, "".autotmp_0005+80(SP)
    0x0072 00114 (a_test.go:13) MOVQ    "".n+48(SP), AX
    0x0077 00119 (a_test.go:13) INCQ    AX
    0x007a 00122 (a_test.go:13) NOP
    0x007a 00122 (a_test.go:13) JMP 30
    0x007c 00124 (a_test.go:16) ADDQ    $88, SP
    0x0080 00128 (a_test.go:16) RET
    0x0081 00129 (a_test.go:11) CALL    runtime.morestack_noctxt(SB)
    0x0086 00134 (a_test.go:11) JMP 0

关于Golang : make slice performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33324912/

有关Golang : make slice performance的更多相关文章

  1. 华为OD机试Golang解题 - 任务总执行时长 - 2

    华为Od必看系列华为OD机试全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理已参加机试人员的实战技巧华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典文章目录华为Od必看系列使用说明本期题目:任务总执行时长题目输入输出示例一输入输出说明go代码实现华为OD其它语言版本

  2. 【编程实践】Golang 获取HTTP请求的IP地址 - 2

    目录Golang获取HTTP请求的IP地址HTTP的发展历史3,HTTP所在的网络层次4,HTTP请求与响应

  3. Golang SQL 查询语法 - 2

    关闭。这个问题需要debuggingdetails.它目前不接受答案。编辑问题以包含desiredbehavior,aspecificproblemorerror,andtheshortestcodenecessarytoreproducetheproblem.这将有助于其他人回答问题。关闭4年前。Improvethisquestion在golang代码中使用sql查询获取语法错误。golang中此SQL查询所需的正确语法:rows,errQuery:=dbCon.Query("SELECTB.LatestDate,A.SVRNameASServerName,A.DRIVE,A.Tot

  4. go - 在golang中的表达式中检查括号是否平衡[保持] - 2

    给定表达式字符串exp,编写程序检查exp中“{”、“}”、“(”、“)”、“[”、“]的对和顺序是否正确。packagemainimport("fmt"stack"github.com/golang-collections/collections/stack")funcmain(){s:="(a[0]+b[2c[6]])){24+53}"stackO:=stack.New()stackmap:=map[string]string{"[":"]","(":")","{":"}"}varstr=""for_,num:=ranges{str=string(num)if(str=="{"||

  5. Golang libphonenumber - 2

    关闭。这个问题是notreproducibleorwascausedbytypos.它目前不接受答案。这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topic在这里,这个问题的解决方式不太可能帮助future的读者。关闭3年前。Improvethisquestion如何通过使用此库在golang中传递数字来获取国家代码:https://godoc.org/github.com/nyaruka/phonenumbers?

  6. go - func 的语法 Golang 错误 - 2

    为什么下面的代码会抛出意外的函数错误?我看到错误./func_correct.go:4:syntaxerror:unexpectedfunc,expectingnamepackagemainfunc(st*Stack)Pop()int{v:=0forix:=len(st)-1;ix>=0;ix--{ifv=st[ix];v!=0{st[ix]=0returnv}}return0}funcmain(){Pop()} 最佳答案 定义堆栈类型在main中为其创建一个变量对其调用Pop代码:packagemainimport"fmt"typ

  7. go - 进程花费了太长时间程序退出:Golang错误 - 2

    Thisquestionalreadyhasanswershere:ForloopoftwovariablesinGo(3个答案)2年前关闭。我正在通过Gotour在Go中使用for循环我跑的时候packagemainimport"fmt"funcmain(){sum:=1forsum程序运行正常,输出为1024但是当我更改sum:=0时packagemainimport"fmt"funcmain(){sum:=0forsum它给出了错误的说法processtooktoolongProgramexited.编辑:我沉迷于Go巡回赛,以至于我无法意识到,我犯了一个逻辑错误:P。

  8. json - 如何在golang中将结构解码到 map 中 - 2

    关闭。这个问题需要debuggingdetails.它目前不接受答案。编辑问题以包含desiredbehavior,aspecificproblemorerror,andtheshortestcodenecessarytoreproducetheproblem.这将有助于其他人回答问题。关闭4年前。Improvethisquestion我有一个Json:{"id":"me","name":"myname","planets":{"EARTH":3,"MARS":4}}我不知道如何将planets字段解码为map[string]int,所以我将访问元素而无需解码它们,就像在这个例子中一样

  9. mysql - golang MySQL "connection refused" - 2

    我是Go(Golang)的新手。我写了一个简单的基准程序来测试MySQL的并发处理。当我增加并发channel数时,不断收到“dialtcp52.55.254.165:3306:getsockopt:connectionrefused”、“unexpectedEOF”错误。每个go例程都将1到n行批量插入到一个简单的客户表中。该程序允许设置可变插入大小(单个语句中的行数)和并行go例程的数量(每个go例程执行上面的一个插入)。程序在小数字row寻找线索。基于它们,我设置了数据库最大连接数以及“max_allowed_pa​​cket”和“max_connections”。我还设置了go

  10. go - Golang "func (t *SomeType) myFuncName(param1, param2)"语法是什么意思 - 2

    这个问题在这里已经有了答案:Functiondeclarationsyntax:thingsinparenthesisbeforefunctionname(3个答案)WhatsthedifferenceoffunctionsandmethodsinGo?(5个答案)ParameterbeforethefunctionnameinGo?[duplicate](1个回答)WhatdothebracketsafterfuncmeaninGo?[duplicate](1个回答)关闭8个月前。我正在学习Golang-在教程中我经常看到这样的语法:typeSomeTypestruct{//stru

随机推荐