Last active
February 17, 2022 08:33
-
-
Save kougazhang/d64ffd8fba3d139192a5e3e85752c680 to your computer and use it in GitHub Desktop.
#golang #benchmark
This file contains 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
package transform | |
import ( | |
"fmt" | |
"sync" | |
"testing" | |
) | |
func TestSliceRest(t *testing.T) { | |
arr := make([]int, 0, 100) | |
arr = append(arr, 1, 2, 3) | |
fmt.Println(arr) | |
arr = arr[:0] | |
fmt.Println(arr) // [] | |
} | |
// 无slice: | |
// Benchmark_string 240 4950748 ns/op 164018 B/op 5 allocs/op | |
func Benchmark_string(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
sendChanStr() | |
} | |
} | |
// 使用 arr: | |
// Benchmark_arr 2265 519549 ns/op 163987 B/op 4 allocs/op | |
func Benchmark_arr(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
sendChanArr() | |
} | |
} | |
// 使用 slice | |
// Benchmark_slice 2227 530600 ns/op 163987 B/op 4 allocs/op | |
func Benchmark_slice(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
sendChanSlice() | |
} | |
} | |
// 发送数组时重置的几种方法 | |
func TestNewParser2BatchRes3(t *testing.T) { | |
sendChan4() // 错误写法, slice 引用的是 arr 的地址, arr 重新赋值后 arr 地址不会变 | |
sendChan5() // 正确写法, channel 发送 array | |
sendChan6() // 错误写法, channel 发送 slice, 使用重新切片重置数组 | |
sendChan7() // 正确写法, channel 发送 slice, 使用make重置数组 | |
} | |
//[0 1 2 3 4 5 6 7 8 9] | |
//[10 11 12 13 14 15 16 17 18 19] | |
//[20 21 22 23 24 25 26 27 28 29] | |
//[30 31 32 33 34 35 36 37 38 39] | |
//[40 41 42 43 44 45 46 47 48 49] | |
//[50 51 52 53 54 55 56 57 58 59] | |
//[60 61 62 63 64 65 66 67 68 69] | |
//[70 71 72 73 74 75 76 77 78 79] | |
//[80 81 82 83 84 85 86 87 88 89] | |
//[90 91 92 93 94 95 96 97 98 99] | |
func sendChan7() { | |
recv := make(chan []int, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
fmt.Println(d) | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
arr := make([]int, 0, 10) | |
var counter int | |
fmt.Printf("raw %p\n", &arr) | |
for i := 0; i < 100; i++ { | |
arr = append(arr, i) | |
counter++ | |
if counter == 10 { | |
recv <- arr | |
counter = 0 | |
arr = make([]int, 0, 10) | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
//[90 91 92 93 94 95 96 97 98 99] | |
func sendChan6() { | |
recv := make(chan []int, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
fmt.Println(d) | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
arr := make([]int, 0, 10) | |
var counter int | |
fmt.Printf("raw %p\n", &arr) | |
for i := 0; i < 100; i++ { | |
arr = append(arr, i) | |
counter++ | |
if counter == 10 { | |
recv <- arr | |
counter = 0 | |
arr = arr[:0] | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
//[0 1 2 3 4 5 6 7 8 9] | |
//[10 11 12 13 14 15 16 17 18 19] | |
//[20 21 22 23 24 25 26 27 28 29] | |
//[30 31 32 33 34 35 36 37 38 39] | |
//[40 41 42 43 44 45 46 47 48 49] | |
//[50 51 52 53 54 55 56 57 58 59] | |
//[60 61 62 63 64 65 66 67 68 69] | |
//[70 71 72 73 74 75 76 77 78 79] | |
//[80 81 82 83 84 85 86 87 88 89] | |
//[90 91 92 93 94 95 96 97 98 99] | |
func sendChan5() { | |
recv := make(chan [10]int, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
fmt.Println(d) | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
var arr [10]int | |
var counter int | |
fmt.Printf("raw %p\n", &arr) | |
for i := 0; i < 100; i++ { | |
arr[counter] = i | |
counter++ | |
if counter == 10 { | |
recv <- arr | |
counter = 0 | |
arr = [10]int{} | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
// 错误写法输出 | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
//[99 0 0 0 0 0 0 0 0 0] | |
func sendChan4() { | |
recv := make(chan []int, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
fmt.Println(d) | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
var arr [10]int | |
var counter int | |
fmt.Printf("raw %p\n", &arr) | |
for i := 0; i < 100; i++ { | |
arr[counter] = i | |
counter++ | |
if counter == 9 { | |
recv <- arr[:] // slice 引用的是 arr 的地址 | |
counter = 0 | |
arr = [10]int{} // arr 的地址不会变 | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
func sendChanSlice() { | |
line := `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | |
recv := make(chan [100]string, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
for range d { | |
} | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
var arr [100]string | |
var counter int | |
for i := 0; i < 100000; i++ { | |
arr[counter] = line | |
counter++ | |
if counter == 100 { | |
recv <- arr | |
counter = 0 | |
arr = [100]string{} | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
func sendChanArr() { | |
line := `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | |
recv := make(chan [100]string, 100) | |
var wg sync.WaitGroup | |
go func() { | |
for d := range recv { | |
for range d { | |
} | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
var arr [100]string | |
var counter int | |
for i := 0; i < 100000; i++ { | |
arr[counter] = line | |
counter++ | |
if counter == 100 { | |
recv <- arr | |
counter = 0 | |
arr = [100]string{} | |
} | |
} | |
close(recv) | |
wg.Wait() | |
} | |
func sendChanStr() { | |
line := `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | |
recv := make(chan string, 10000) | |
var wg sync.WaitGroup | |
var counter int | |
go func() { | |
for range recv { | |
counter++ | |
} | |
wg.Done() | |
}() | |
wg.Add(1) | |
for i := 0; i < 100000; i++ { | |
recv <- line | |
} | |
close(recv) | |
wg.Wait() | |
} |
使用 copy
释放数组:
参见:https://geektutu.com/post/hpg-slice.html
func lastNumsBySlice(origin []int) []int {
return origin[len(origin)-2:]
}
func lastNumsByCopy(origin []int) []int {
result := make([]int, 2)
copy(result, origin[len(origin)-2:])
return result
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
切片是对数组的引用,使用
[:]
时底层指向的数组仍然是相同的。数组是一段连续的地址空间,重复使用可以节约内存,详见:使用 slice 的用法, https://blog.thinkeridea.com/201901/go/slice_de_yi_xie_shi_yong_ji_qiao.html 这篇文章提到的技巧非常非常强!