ginuerzh / gost

GO Simple Tunnel - a simple tunnel written in golang
MIT License
15.84k stars 2.47k forks source link

server.go 当中 从sync.Pool中取出来的[]byte 是否更应该用 *[]byte #773

Closed shoaly closed 2 years ago

shoaly commented 2 years ago

具体原因参照: https://staticcheck.io/docs/checks#SA6002

server.go中 对应片段, 改成: func copyBuffer(dst io.Writer, src io.Reader) error { buf := lPool.Get().(*[]byte) defer lPool.Put(buf)

_, err := io.CopyBuffer(dst, src, *buf)
return err

}

shoaly commented 2 years ago

在补充一个 benchmark测试, 分别测试用指针, 不用指针, 不用sync.Pool的, 测试结果 如果用指针的话, 性能还是好了不少, 甚至不用sync.Pool性能还还排第二 [0106]添加一个压力测试, 用*bytes.Buffer的场景, 效率也不行, 和池子2号差不多的性能

BenchmarkBufferWithPool1-8 36153943 158.6 ns/op 0 B/op 0 allocs/op BenchmarkBufferWithPool2-8 2840011 2110 ns/op 10310 B/op 3 allocs/op BenchmarkBufferWithoutPool-8 20515170 259.2 ns/op 0 B/op 0 allocs/op BenchmarkBufferWithPool3-8 2973811 2007 ns/op 10310 B/op 2 allocs/op

代码如下:

package main

import (
    "bytes"
    "sync"
    "testing"
)

//go test -bench="Benchmark" -benchtime=5s -benchmem

var bufferPool1 = sync.Pool{
    New: func() interface{} {
        data := make([]byte, 10000)
        return &data
    },
}

var bufferPool2 = sync.Pool{
    New: func() interface{} {
        data := make([]byte, 10000)
        return data
    },
}

var bufferPool3 = sync.Pool{
    New: func() interface{} {
        data := bytes.NewBuffer(make([]byte, 0, 10000))
        return data
    },
}

var data = make([]byte, 10000)

func BenchmarkBufferWithPool1(b *testing.B) {
    for n := 0; n < b.N; n++ {
        buf := bufferPool1.Get().(*[]byte)
        copy(*buf, data)
        bufferPool1.Put(buf)
    }
}

func BenchmarkBufferWithPool2(b *testing.B) {
    for n := 0; n < b.N; n++ {
        buf := bufferPool2.Get().([]byte)
        copy(buf, data)
        bufferPool1.Put(buf)
    }
}

func BenchmarkBufferWithoutPool(b *testing.B) {
    for n := 0; n < b.N; n++ {
        buf := make([]byte, 10000)
        copy(buf, data)
    }
}

func BenchmarkBufferWithPool3(b *testing.B) {
    for n := 0; n < b.N; n++ {
        buf := bufferPool3.Get().(*bytes.Buffer)
        // copy(buf, data)
        buf.Write(data)
        buf.Reset()
        bufferPool1.Put(buf)
    }
}
f4nff commented 2 years ago

测试结果是啥? gost确实占用内存比较大,

shoaly commented 2 years ago

测试结果是啥? gost确实占用内存比较大, 感觉用了sync.Pool 又没有享受到他的优势

f4nff commented 2 years ago

用哪个好?

ginuerzh commented 2 years ago

使用*bytes.Buffer是不是要比[]byte更好一些,毕竟[]byte这种形式还是很少见的。

shoaly commented 2 years ago

使用bytes.Buffer是不是要比[]byte更好一些,毕竟*[]byte这种形式还是很少见的。

已经做过测试, 并更新到上面, 可以看一下, 结论是 bytes.Buffer 也不是很好, 还是裸 []byte 胜出

lyyx5858 commented 2 years ago

使用bytes.Buffer是不是要比[]byte更好一些,毕竟*[]byte这种形式还是很少见的。

已经做过测试, 并更新到上面, 可以看一下, 结论是 bytes.Buffer 也不是很好, 还是裸 []byte 胜出

与pool 的size有关系吗?设多大的性能最优?

shoaly commented 2 years ago

使用bytes.Buffer是不是要比[]byte更好一些,毕竟*[]byte这种形式还是很少见的。

已经做过测试, 并更新到上面, 可以看一下, 结论是 bytes.Buffer 也不是很好, 还是裸 []byte 胜出

与pool 的size有关系吗?设多大的性能最优?

本身用 这个pool就是借助他的弹性伸缩能力, 如果配置size 反而不够智能了把

lyyx5858 commented 2 years ago

使用bytes.Buffer是不是要比[]byte更好一些,毕竟*[]byte这种形式还是很少见的。

已经做过测试, 并更新到上面, 可以看一下, 结论是 bytes.Buffer 也不是很好, 还是裸 []byte 胜出

与pool 的size有关系吗?设多大的性能最优?

本身用 这个pool就是借助他的弹性伸缩能力, 如果配置size 反而不够智能了把

我将你的测试程序里的10000改成5000后,池子2和4的线性的,但池子1和3不是线性关系,的确奇怪。

shoaly commented 2 years ago

他们的性能排序 有变动么, 如果有变动 可以接着讨论测试了, 如果排序没有变化 我感觉还可以维持当前的结论撒

ginuerzh commented 2 years ago

V3版本中已经改为使用*[]byte了。

lyyx5858 commented 2 years ago

V3版本中已经改为使用*[]byte了。

建议将V2版本也改成*[]byte.