From cd1474871eccfb699d228eadd28d4f8e433a2fdc Mon Sep 17 00:00:00 2001 From: Jayant Date: Tue, 7 May 2024 17:50:07 +0800 Subject: [PATCH] perf: use dirtmake to reduce memclr cost (#321) --- go.mod | 4 ++-- go.sum | 13 +++++++++---- nocopy.go | 3 ++- nocopy_linkbuffer.go | 12 +++++++----- nocopy_linkbuffer_test.go | 3 +++ 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2e73daa5..b9a2a4bf 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module github.com/cloudwego/netpoll go 1.15 require ( - github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 - golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe + github.com/bytedance/gopkg v0.0.0-20240507064146-197ded923ae3 + golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 ) diff --git a/go.sum b/go.sum index 32a454e1..49445cde 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 h1:PtwsQyQJGxf8iaPptPNaduEIu9BnrNms+pcRdHAxZaM= -github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7/go.mod h1:2ZlV9BaUH4+NXIBF0aMdKKAnHTzqH+iMU4KUjAbL23Q= +github.com/bytedance/gopkg v0.0.0-20240507064146-197ded923ae3 h1:ZKUHguI38SRQJkq7hhmwn8lAv3xM6B5qkj1IneS15YY= +github.com/bytedance/gopkg v0.0.0-20240507064146-197ded923ae3/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -7,9 +7,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe h1:W8vbETX/n8S6EmY0Pu4Ix7VvpsJUESTwl0oCK8MJOgk= -golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/nocopy.go b/nocopy.go index 6df02e8f..53acab2c 100644 --- a/nocopy.go +++ b/nocopy.go @@ -19,6 +19,7 @@ import ( "reflect" "unsafe" + "github.com/bytedance/gopkg/lang/dirtmake" "github.com/bytedance/gopkg/lang/mcache" ) @@ -285,7 +286,7 @@ func unsafeStringToSlice(s string) (b []byte) { // malloc limits the cap of the buffer from mcache. func malloc(size, capacity int) []byte { if capacity > mallocMax { - return make([]byte, size, capacity) + return dirtmake.Bytes(size, capacity) } return mcache.Malloc(size, capacity) } diff --git a/nocopy_linkbuffer.go b/nocopy_linkbuffer.go index cb48cad1..2f4f3364 100644 --- a/nocopy_linkbuffer.go +++ b/nocopy_linkbuffer.go @@ -20,6 +20,8 @@ import ( "fmt" "sync" "sync/atomic" + + "github.com/bytedance/gopkg/lang/dirtmake" ) // BinaryInplaceThreshold marks the minimum value of the nocopy slice length, @@ -91,7 +93,7 @@ func (b *UnsafeLinkBuffer) Next(n int) (p []byte, err error) { p = malloc(n, n) b.caches = append(b.caches, p) } else { - p = make([]byte, n) + p = dirtmake.Bytes(n, n) } var l int for ack := n; ack > 0; ack = ack - l { @@ -128,7 +130,7 @@ func (b *UnsafeLinkBuffer) Peek(n int) (p []byte, err error) { p = malloc(n, n) b.caches = append(b.caches, p) } else { - p = make([]byte, n) + p = dirtmake.Bytes(n, n) } var node = b.read var l int @@ -232,11 +234,11 @@ func (b *UnsafeLinkBuffer) readBinary(n int) (p []byte) { } } // if the underlying buffer too large, we shouldn't use no-copy mode - p = make([]byte, n) + p = dirtmake.Bytes(n, n) copy(p, b.read.Next(n)) return p } - p = make([]byte, n) + p = dirtmake.Bytes(n, n) // multiple nodes var pIdx int var l int @@ -560,7 +562,7 @@ func (b *UnsafeLinkBuffer) Bytes() []byte { return node.buf[node.off:] } n := 0 - p := make([]byte, b.Len()) + p := dirtmake.Bytes(b.Len(), b.Len()) for ; node != flush; node = node.next { if node.Len() > 0 { n += copy(p[n:], node.buf[node.off:]) diff --git a/nocopy_linkbuffer_test.go b/nocopy_linkbuffer_test.go index 25770762..8a9f8cfe 100644 --- a/nocopy_linkbuffer_test.go +++ b/nocopy_linkbuffer_test.go @@ -668,9 +668,12 @@ func TestLinkBufferIndexByte(t *testing.T) { trigger := make(chan struct{}, 16) lb := NewLinkBuffer() + empty := make([]byte, 1002) go func() { for i := 0; i < loopSize; i++ { buf, err := lb.Malloc(1002) + // need clear buffer + copy(buf, empty) buf[500] = '\n' buf[1001] = '\n' MustNil(t, err)