Last active
March 15, 2024 02:43
-
-
Save dazuiba/3a3943745d8c984f11e2f155c75eb2b5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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