Pointers 基准测试时,指针接收器不快于值接收器

Pointers 基准测试时,指针接收器不快于值接收器,pointers,go,Pointers,Go,这是我正在测试的代码,我希望看到在基准测试时,基于指针的addDataPointer将比基于addData值的函数执行得更快。为什么两者之间的性能没有显著变化 package main import "fmt" type BigStruct struct { name string data []byte } func addData(s BigStruct) BigStruct { s.data = append([]byte{0x00, 0x01, 0x02,

这是我正在测试的代码,我希望看到在基准测试时,基于指针的addDataPointer将比基于addData值的函数执行得更快。为什么两者之间的性能没有显著变化

package main

import "fmt"

type BigStruct struct {
    name string
    data []byte
}

func addData(s BigStruct) BigStruct {
    s.data = append([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, s.data...)
    return BigStruct{name: s.name, data: s.data}
}

func (s *BigStruct) addDataPointer() {
    s.data = append([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, s.data...)
}

func main() {
    a := BigStruct{name: "greg", data: []byte("abc")}
    b := &BigStruct{name: "greg", data: []byte("abc")}
    fmt.Println(addData(a))
    b.addDataPointer()
    fmt.Println(*b)
}

func BenchmarkBigLenPointer(b *testing.B) {
    for i := 0; i < b.N; i++ {
        big := &BigStruct{name: "greg", data: []byte(strings.Repeat("test1234", 1024))}
        big.addDataPointer()
    }
}

func BenchmarkBigLen(b *testing.B) {
    for i := 0; i < b.N; i++ {
        big := BigStruct{name: "greg", data: []byte(strings.Repeat("test1234", 1024))}
        addData(big)
    }
主程序包
输入“fmt”
类型BigStruct struct{
名称字符串
数据[]字节
}
func addData(s BigStruct)BigStruct{
s、 数据=追加([]字节{0x00,0x01,0x02,0x03,0x04,0x05},s.data…)
返回BigStruct{name:s.name,data:s.data}
}
func(s*BigStruct)addDataPointer(){
s、 数据=追加([]字节{0x00,0x01,0x02,0x03,0x04,0x05},s.data…)
}
func main(){
a:=BigStruct{name:“greg”,数据:[]字节(“abc”)}
b:=&BigStruct{name:“greg”,数据:[]字节(“abc”)}
格式打印LN(添加数据(a))
b、 addDataPointer()
格式打印项次(*b)
}
func BenchmarkBigLenPointer(b*testing.b){
对于i:=0;i
您的基准函数为
循环测量
中的任何内容,例如:

    big := &BigStruct{name: "greg", data: []byte(strings.Repeat("test1234", 1024))}
    big.addDataPointer()
以及:

因此,您还可以对
strings.Repeat()
进行基准测试,这将为您提供一个长
字符串
值,您还可以将其转换为
[]字节
,这将复制这个长
字符串

这些函数的执行时间远远大于
addDataPointer()
方法和
addData()
函数的执行时间

将转换和
字符串移动到
循环的
之外。Repeat()
调用,如下所示:

func BenchmarkBigLenPointer(b *testing.B) {
    s := []byte(strings.Repeat("test1234", 1024))
    for i := 0; i < b.N; i++ {
        big := &BigStruct{name: "greg", data: s}
        big.addDataPointer()
    }
}

func BenchmarkBigLen(b *testing.B) {
    s := []byte(strings.Repeat("test1234", 1024))
    for i := 0; i < b.N; i++ {
        big := BigStruct{name: "greg", data: s}
        addData(big)
    }
}
func BenchmarkBigLenPointer(b*testing.b){
s:=[]字节(字符串。重复(“test1234”,1024))
对于i:=0;i
现在,测量方法和函数的时间更为准确。但即使对其进行基准测试,也会得到基准测试结果,结果显示
addData()
addDataPointer()
的执行时间非常接近

对此的解释是,在函数的情况下,您传递一个包含字节片的结构值。Go中的片是小描述符(类似于结构的头),它不包含片的元素,只包含一个指向支持数组的指针。因此,片值的大小是相同的,无论其长度(元素数)如何.要查看切片标头中的内容,请检查类型

因此,函数的开销很小,这可能会增加一点执行时间,但另一方面,指针方法需要取消对指针的引用,这会增加一点执行时间。最后,它们非常接近。在这种情况下,没有太大区别

func BenchmarkBigLenPointer(b *testing.B) {
    s := []byte(strings.Repeat("test1234", 1024))
    for i := 0; i < b.N; i++ {
        big := &BigStruct{name: "greg", data: s}
        big.addDataPointer()
    }
}

func BenchmarkBigLen(b *testing.B) {
    s := []byte(strings.Repeat("test1234", 1024))
    for i := 0; i < b.N; i++ {
        big := BigStruct{name: "greg", data: s}
        addData(big)
    }
}