Skip to content

Instantly share code, notes, and snippets.

@dazuiba
Last active March 15, 2024 02:43
Show Gist options
  • Save dazuiba/3a3943745d8c984f11e2f155c75eb2b5 to your computer and use it in GitHub Desktop.
Save dazuiba/3a3943745d8c984f11e2f155c75eb2b5 to your computer and use it in GitHub Desktop.
/**
type v10 struct {
data [10]byte
}
//函数参数,指针
//当struct大小在1K时,指针传递(无拷贝)快1个数量级。低于1K差别不大
func BenchmarkPointer10In(b *testing.B) {
var v v10
for i := 0; i < b.N; i++ {
readMiddle10p(&v)
}
}
func readMiddle10p(v *v10) {
x = v.data[5]
}
//函数参数,传值
func BenchmarkValue10In(b *testing.B) {
var v v10
for i := 0; i < b.N; i++ {
readMiddle10(v)
}
}
func readMiddle10(v v10) {
x = v.data[5]
}
//函数返回,传值
//当struct大小10k以下时,用值传递更优(多一次拷贝,但垃圾回收更简单,快5倍)
func BenchmarkValue10Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10v()
x = v.data[5]
}
}
func get10v() v10 {
var v v10
return v
}
//函数返回,指针
func BenchmarkPointer10Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10p()
x = v.data[5]
}
}
func get10p() *v10 {
var v v10
return &v
}
*/
/**
//指针作为参数
BenchmarkPTR10In-10 1000000000 0.9504 ns/op
BenchmarkVAL10In-10 1000000000 0.9548 ns/op
BenchmarkPTR100In-10 1000000000 0.9629 ns/op
BenchmarkVAL100In-10 427136516 2.803 ns/op
//1K时,值传递(拷贝)慢1个数量级
BenchmarkPTR1_000In-10 1000000000 0.9453 ns/op
BenchmarkVAL1_000In-10 60044658 20.20 ns/op
BenchmarkPTR100_000In-10 587816641 2.035 ns/op
BenchmarkVAL100_000In-10 595599 2010 ns/op
BenchmarkPTR1_000_000In-10 580347966 2.059 ns/op
BenchmarkVAL1_000_000In-10 58912 20497 ns/op
BenchmarkPTR10_000_000In-10 582672176 2.054 ns/op
BenchmarkVAL10_000_000In-10 5100 233208 ns/op
//指针作为返回值
//10k以下时,用值传递更优
BenchmarkPTR10Out-10 97847692 11.97 ns/op 16 B/op 1 allocs/op
BenchmarkVAL10Out-10 579650754 2.064 ns/op 0 B/op 0 allocs/op
BenchmarkPTR100Out-10 47784967 24.23 ns/op 112 B/op 1 allocs/op
BenchmarkVAL100Out-10 155825798 7.654 ns/op 0 B/op 0 allocs/op
BenchmarkPTR1_000Out-10 7072693 152.4 ns/op 1024 B/op 1 allocs/op
BenchmarkVAL1_000Out-10 22828824 52.58 ns/op 0 B/op 0 allocs/op
//10k时性能反转,用ptr更优
BenchmarkPTR100_000Out-10 214401 5383 ns/op 106496 B/op 1 allocs/op
BenchmarkVAL100_000Out-10 197953 6094 ns/op 0 B/op 0 allocs/op
BenchmarkPTR1_000_000Out-10 28195 40736 ns/op 1007618 B/op 1 allocs/op
BenchmarkVAL1_000_000Out-10 19198 61951 ns/op 0 B/op 0 allocs/op
BenchmarkPTR10_000_000Out-10 4902 221070 ns/op 10002441 B/op 1 allocs/op
BenchmarkVAL10_000_000Out-10 1873 642765 ns/op 0 B/op 0 allocs/op
*/
package main
import "testing"
var x byte
//go:noinline
func BenchmarkPointer10In(b *testing.B) {
var v v10
for i := 0; i < b.N; i++ {
readMiddle10p(&v)
}
}
//go:noinline
func BenchmarkValue10In(b *testing.B) {
var v v10
for i := 0; i < b.N; i++ {
readMiddle10(v)
}
}
//go:noinline
func BenchmarkPointer10Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10p()
x = v.data[5]
}
}
//go:noinline
func BenchmarkValue10Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10v()
x = v.data[5]
}
}
type v10 struct {
data [10]byte
}
//go:noinline
func readMiddle10(v v10) {
x = v.data[5]
}
//go:noinline
func readMiddle10p(v *v10) {
x = v.data[5]
}
//go:noinline
func get10p() *v10 {
var v v10
return &v
}
//go:noinline
func get10v() v10 {
var v v10
return v
}
//go:noinline
func BenchmarkPointer100In(b *testing.B) {
var v v100
for i := 0; i < b.N; i++ {
readMiddle100p(&v)
}
}
//go:noinline
func BenchmarkValue100In(b *testing.B) {
var v v100
for i := 0; i < b.N; i++ {
readMiddle100(v)
}
}
//go:noinline
func BenchmarkPointer100Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get100p()
x = v.data[50]
}
}
//go:noinline
func BenchmarkValue100Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get100v()
x = v.data[50]
}
}
type v100 struct {
data [100]byte
}
//go:noinline
func readMiddle100(v v100) {
x = v.data[50]
}
//go:noinline
func readMiddle100p(v *v100) {
x = v.data[50]
}
//go:noinline
func get100p() *v100 {
var v v100
return &v
}
//go:noinline
func get100v() v100 {
var v v100
return v
}
//go:noinline
func BenchmarkPointer1_000In(b *testing.B) {
var v v1_000
for i := 0; i < b.N; i++ {
readMiddle1_000p(&v)
}
}
//go:noinline
func BenchmarkValue1_000In(b *testing.B) {
var v v1_000
for i := 0; i < b.N; i++ {
readMiddle1_000(v)
}
}
//go:noinline
func BenchmarkPointer1_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get1_000p()
x = v.data[500]
}
}
//go:noinline
func BenchmarkValue1_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get1_000v()
x = v.data[500]
}
}
type v1_000 struct {
data [1_000]byte
}
//go:noinline
func readMiddle1_000(v v1_000) {
x = v.data[500]
}
//go:noinline
func readMiddle1_000p(v *v1_000) {
x = v.data[500]
}
//go:noinline
func get1_000p() *v1_000 {
var v v1_000
return &v
}
//go:noinline
func get1_000v() v1_000 {
var v v1_000
return v
}
//go:noinline
func BenchmarkPointer100_000In(b *testing.B) {
var v v100_000
for i := 0; i < b.N; i++ {
readMiddle100_000p(&v)
}
}
//go:noinline
func BenchmarkValue100_000In(b *testing.B) {
var v v100_000
for i := 0; i < b.N; i++ {
readMiddle100_000(v)
}
}
//go:noinline
func BenchmarkPointer100_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get100_000p()
x = v.data[50_000]
}
}
//go:noinline
func BenchmarkValue100_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get100_000v()
x = v.data[50_000]
}
}
type v100_000 struct {
data [100_000]byte
}
//go:noinline
func readMiddle100_000(v v100_000) {
x = v.data[50_000]
}
//go:noinline
func readMiddle100_000p(v *v100_000) {
x = v.data[50_000]
}
//go:noinline
func get100_000p() *v100_000 {
var v v100_000
return &v
}
//go:noinline
func get100_000v() v100_000 {
var v v100_000
return v
}
//go:noinline
func BenchmarkPointer1_000_000In(b *testing.B) {
var v v1_000_000
for i := 0; i < b.N; i++ {
readMiddle1_000_000p(&v)
}
}
//go:noinline
func BenchmarkValue1_000_000In(b *testing.B) {
var v v1_000_000
for i := 0; i < b.N; i++ {
readMiddle1_000_000(v)
}
}
//go:noinline
func BenchmarkPointer1_000_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get1_000_000p()
x = v.data[500_000]
}
}
//go:noinline
func BenchmarkValue1_000_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get1_000_000v()
x = v.data[500_000]
}
}
type v1_000_000 struct {
data [1_000_000]byte
}
//go:noinline
func readMiddle1_000_000(v v1_000_000) {
x = v.data[500_000]
}
//go:noinline
func readMiddle1_000_000p(v *v1_000_000) {
x = v.data[500_000]
}
//go:noinline
func get1_000_000p() *v1_000_000 {
var v v1_000_000
return &v
}
//go:noinline
func get1_000_000v() v1_000_000 {
var v v1_000_000
return v
}
//go:noinline
func BenchmarkPointer10_000_000In(b *testing.B) {
var v v10_000_000
for i := 0; i < b.N; i++ {
readMiddle10_000_000p(&v)
}
}
//go:noinline
func BenchmarkValue10_000_000In(b *testing.B) {
var v v10_000_000
for i := 0; i < b.N; i++ {
readMiddle10_000_000(v)
}
}
//go:noinline
func BenchmarkPointer10_000_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10_000_000p()
x = v.data[5_000_000]
}
}
//go:noinline
func BenchmarkValue10_000_000Out(b *testing.B) {
for i := 0; i < b.N; i++ {
v := get10_000_000v()
x = v.data[5_000_000]
}
}
type v10_000_000 struct {
data [10_000_000]byte
}
//go:noinline
func readMiddle10_000_000(v v10_000_000) {
x = v.data[5_000_000]
}
//go:noinline
func readMiddle10_000_000p(v *v10_000_000) {
x = v.data[5_000_000]
}
//go:noinline
func get10_000_000p() *v10_000_000 {
var v v10_000_000
return &v
}
//go:noinline
func get10_000_000v() v10_000_000 {
var v v10_000_000
return v
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment