1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

improve binary.Writer

This commit is contained in:
wdvxdr 2021-03-12 15:55:50 +08:00
parent 790c33e037
commit 93534fe94a
No known key found for this signature in database
GPG Key ID: 55FF1414A69CEBA6
4 changed files with 177 additions and 17 deletions

View File

@ -5,26 +5,51 @@ import (
"encoding/binary"
)
type Writer struct {
buf *bytes.Buffer
type Writer bytes.Buffer
/*
var bufferPool = sync.Pool{ // todo sync.Pool 无法通过单元测试
New: func() interface{} {
return new(bytes.Buffer)
},
}
func NewBuffer() *bytes.Buffer {
return bufferPool.Get().(*bytes.Buffer)
}
func PutBuffer(buf *bytes.Buffer) {
// See https://golang.org/issue/23199
const maxSize = 1 << 16
if buf.Cap() < maxSize { // 对于大Buffer直接丢弃
buf.Reset()
bufferPool.Put(buf)
}
}
*/
func NewWriter() *Writer {
return &Writer{buf: new(bytes.Buffer)}
return new(Writer)
}
/*
func PutWriter(w *Writer) {
PutBuffer((*bytes.Buffer)(w))
}
*/
func NewWriterF(f func(writer *Writer)) []byte {
w := NewWriter()
f(w)
w := new(bytes.Buffer)
f((*Writer)(w))
return w.Bytes()
}
func (w *Writer) Write(b []byte) {
w.buf.Write(b)
(*bytes.Buffer)(w).Write(b)
}
func (w *Writer) WriteByte(b byte) {
w.buf.WriteByte(b)
(*bytes.Buffer)(w).WriteByte(b)
}
func (w *Writer) WriteUInt16(v uint16) {
@ -70,9 +95,7 @@ func (w *Writer) EncryptAndWrite(key []byte, data []byte) {
}
func (w *Writer) WriteIntLvPacket(offset int, f func(writer *Writer)) {
t := NewWriter()
f(t)
data := t.Bytes()
data := NewWriterF(f)
w.WriteUInt32(uint32(len(data) + offset))
w.Write(data)
}
@ -108,5 +131,5 @@ func (w *Writer) WriteTlvLimitedSize(data []byte, limit int) {
}
func (w *Writer) Bytes() []byte {
return w.buf.Bytes()
return (*bytes.Buffer)(w).Bytes()
}

140
binary/writer_test.go Normal file
View File

@ -0,0 +1,140 @@
package binary
import (
"bytes"
"encoding/hex"
"fmt"
"math/rand"
"sync"
"testing"
)
func NewWriterFOld(f func(writer *Writer)) []byte {
w := (*Writer)(new(bytes.Buffer))
f(w)
return w.Bytes()
}
func TestNewWriterF(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 10000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
test := make([]byte, 1024)
rand.Read(test)
b1 := NewWriterFOld(func(writer *Writer) {
writer.Write(test)
writer.Write(NewWriterFOld(func(writer *Writer) {
writer.Write(test)
writer.Write(NewWriterFOld(func(writer *Writer) {
writer.Write(test)
}))
}))
})
b2 := NewWriterF(func(writer *Writer) {
writer.Write(test)
writer.Write(NewWriterF(func(writer *Writer) {
writer.Write(test)
writer.Write(NewWriterF(func(writer *Writer) {
writer.Write(test)
}))
}))
})
if !bytes.Equal(b1, b2) {
fmt.Println(hex.EncodeToString(b1))
fmt.Println(hex.EncodeToString(b2))
t.Error("Not equal!!!")
}
}()
}
wg.Wait()
}
func BenchmarkNewWriterFOld256(b *testing.B) {
test := make([]byte, 256)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterFOld(func(w *Writer) {
w.Write(test)
})
}
})
}
func BenchmarkNewWriterF256(b *testing.B) {
test := make([]byte, 256)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterF(func(w *Writer) {
w.Write(test)
})
}
})
}
func BenchmarkNewWriterFOld1024(b *testing.B) {
test := make([]byte, 1024)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterFOld(func(w *Writer) {
w.Write(test)
})
}
})
}
func BenchmarkNewWriterF1024(b *testing.B) {
test := make([]byte, 1024)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterF(func(w *Writer) {
w.Write(test)
})
}
})
}
func BenchmarkNewWriterFOld128_5(b *testing.B) {
test := make([]byte, 128)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterFOld(func(w *Writer) {
w.Write(test)
w.Write(test)
w.Write(test)
w.Write(test)
w.Write(test)
})
}
})
}
func BenchmarkNewWriterF128_5(b *testing.B) {
test := make([]byte, 128)
rand.Read(test)
b.StartTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
NewWriterF(func(w *Writer) {
w.Write(test)
w.Write(test)
w.Write(test)
w.Write(test)
w.Write(test)
})
}
})
}

2
go.mod
View File

@ -5,7 +5,7 @@ go 1.15
require (
github.com/golang/protobuf v1.4.3
github.com/json-iterator/go v1.1.10
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
github.com/modern-go/reflect2 v1.0.1
github.com/pkg/errors v0.9.1
google.golang.org/protobuf v1.25.0
)

7
go.sum
View File

@ -1,7 +1,5 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/a8m/syncmap v0.0.0-20200818084611-4bbbd178de97 h1:QJIAdw5m5tNUy7fjBxgg73+YUs/AkeESeqdJ1L3lN10=
github.com/a8m/syncmap v0.0.0-20200818084611-4bbbd178de97/go.mod h1:f3iF7/3t9i9hsYF8DPgT0XeIVyNzevhMCKf2445Q6pE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -32,8 +30,9 @@ github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -61,8 +60,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190501045030-23463209683d/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=