这是我正在测试的代码,我希望看到基准测试时,基于指针的 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)
}
最佳答案
您的基准函数测量 for
循环内的任何内容,例如:
big := &BigStruct{name: "greg", data: []byte(strings.Repeat("test1234", 1024))}
big.addDataPointer()
和:
big := BigStruct{name: "greg", data: []byte(strings.Repeat("test1234", 1024))}
addData(big)
因此您还对 strings.Repeat()
进行了基准测试,它为您提供了一个很长的 string
值,并且您还将其转换为 []byte
,它会复制这个冗长的 string
。
这些的执行时间比您的 addDataPointer()
方法和 addData()
函数的执行时间要长得多。
将转换和 strings.Repeat()
调用移到 for
循环之外,如下所示:
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)
}
}
现在可以更准确地测量您的方法和函数的时间。但即使您对其进行基准测试,您也会得到基准测试结果,表明 addData()
和 addDataPointer()
的执行时间非常接近。
对此的解释是,在函数的情况下,您传递一个包含字节 slice 的结构值。 Go 中的 slice 是小型描述符(类似于 header 的结构),它不包含 slice 的元素,而仅包含指向支持数组的指针。所以 slice 值的大小是相同的,不管它的长度(元素的数量)如何。要查看 slice header 中的内容,请查看 reflect.SliceHeader
类型。
所以函数的开销很小,这可能会增加它的执行时间,但另一方面指针方法需要取消引用指针,这会增加它的执行时间。最后,他们非常接近。在这种情况下,差别不大。
关于pointers - 基准测试时指针接收器不比值接收器快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40328658/