Jelajahi Sumber

small buffer

Darien Raymond 9 tahun lalu
induk
melakukan
70c75038a2

+ 3 - 12
common/alloc/buffer.go

@@ -205,18 +205,9 @@ func NewBuffer() *Buffer {
 	return mediumPool.Allocate()
 }
 
-// NewLargeBuffer creates a Buffer with 64K bytes of arbitrary content.
-//func NewLargeBuffer() *Buffer {
-//	return largePool.Allocate()
-//}
-
-//func NewBufferWithSize(size int) *Buffer {
-//	if size <= BufferSize {
-//		return NewBuffer()
-//	}
-//
-//	return NewLargeBuffer()
-//}
+func NewSmallBuffer() *Buffer {
+	return smallPool.Allocate()
+}
 
 func NewLocalBuffer(size int) *Buffer {
 	return CreateBuffer(make([]byte, size), nil)

+ 28 - 2
common/alloc/buffer_pool.go

@@ -11,6 +11,31 @@ type Pool interface {
 	Free(*Buffer)
 }
 
+type SyncPool struct {
+	allocator *sync.Pool
+}
+
+func NewSyncPool(bufferSize uint32) *SyncPool {
+	pool := &SyncPool{
+		allocator: &sync.Pool{
+			New: func() interface{} { return make([]byte, bufferSize) },
+		},
+	}
+	return pool
+}
+
+func (p *SyncPool) Allocate() *Buffer {
+	return CreateBuffer(p.allocator.Get().([]byte), p)
+}
+
+func (p *SyncPool) Free(buffer *Buffer) {
+	rawBuffer := buffer.head
+	if rawBuffer == nil {
+		return
+	}
+	p.allocator.Put(rawBuffer)
+}
+
 type BufferPool struct {
 	chain     chan []byte
 	allocator *sync.Pool
@@ -55,14 +80,15 @@ const (
 	mediumBufferByteSize = 8 * 1024
 	BufferSize           = mediumBufferByteSize - defaultOffset
 
-	largeBufferByteSize = 64 * 1024
-	LargeBufferSize     = largeBufferByteSize - defaultOffset
+	smallBufferByteSize = 2 * 1024
+	SmallBufferSize     = smallBufferByteSize - defaultOffset
 
 	PoolSizeEnvKey = "v2ray.buffer.size"
 )
 
 var (
 	mediumPool *BufferPool
+	smallPool  = NewSyncPool(2048)
 )
 
 func init() {

+ 28 - 0
common/alloc/buffer_test.go

@@ -58,3 +58,31 @@ func TestBufferString(t *testing.T) {
 	buffer.AppendString("Test String")
 	assert.String(buffer.String()).Equals("Test String")
 }
+
+func BenchmarkNewBuffer8192(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		buffer := NewBuffer()
+		buffer.Release()
+	}
+}
+
+func BenchmarkNewLocalBuffer8192(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		buffer := NewLocalBuffer(8192)
+		buffer.Release()
+	}
+}
+
+func BenchmarkNewBuffer2048(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		buffer := NewSmallBuffer()
+		buffer.Release()
+	}
+}
+
+func BenchmarkNewLocalBuffer2048(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		buffer := NewLocalBuffer(2048)
+		buffer.Release()
+	}
+}

+ 2 - 2
proxy/shadowsocks/protocol.go

@@ -240,7 +240,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *alloc.Buffer) (*a
 	}
 	account := rawAccount.(*ShadowsocksAccount)
 
-	buffer := alloc.NewLocalBuffer(2048)
+	buffer := alloc.NewSmallBuffer()
 	ivLen := account.Cipher.IVSize()
 	buffer.Slice(0, ivLen)
 	rand.Read(buffer.Value)
@@ -349,7 +349,7 @@ type UDPReader struct {
 }
 
 func (this *UDPReader) Read() (*alloc.Buffer, error) {
-	buffer := alloc.NewLocalBuffer(2048)
+	buffer := alloc.NewSmallBuffer()
 	nBytes, err := this.Reader.Read(buffer.Value)
 	if err != nil {
 		buffer.Release()

+ 3 - 3
transport/internet/authenticators/http/http.go

@@ -41,7 +41,7 @@ type HeaderReader struct {
 }
 
 func (*HeaderReader) Read(reader io.Reader) (*alloc.Buffer, error) {
-	buffer := alloc.NewLocalBuffer(2048)
+	buffer := alloc.NewSmallBuffer()
 	for {
 		_, err := buffer.FillFrom(reader)
 		if err != nil {
@@ -138,7 +138,7 @@ type HttpAuthenticator struct {
 }
 
 func (this HttpAuthenticator) GetClientWriter() *HeaderWriter {
-	header := alloc.NewLocalBuffer(2048).Clear()
+	header := alloc.NewSmallBuffer().Clear()
 	config := this.config.Request
 	header.AppendString(config.Method.GetValue()).AppendString(" ").AppendString(config.PickUri()).AppendString(" ").AppendString(config.GetFullVersion()).AppendString(CRLF)
 
@@ -153,7 +153,7 @@ func (this HttpAuthenticator) GetClientWriter() *HeaderWriter {
 }
 
 func (this HttpAuthenticator) GetServerWriter() *HeaderWriter {
-	header := alloc.NewLocalBuffer(2048).Clear()
+	header := alloc.NewSmallBuffer().Clear()
 	config := this.config.Response
 	header.AppendString(config.GetFullVersion()).AppendString(" ").AppendString(config.Status.GetCode()).AppendString(" ").AppendString(config.Status.GetReason()).AppendString(CRLF)
 

+ 1 - 1
transport/internet/kcp/output.go

@@ -37,7 +37,7 @@ func (this *BufferedSegmentWriter) Write(seg Segment) {
 	}
 
 	if this.buffer == nil {
-		this.buffer = alloc.NewLocalBuffer(2048).Clear()
+		this.buffer = alloc.NewSmallBuffer().Clear()
 	}
 
 	this.buffer.Value = seg.Bytes(this.buffer.Value)

+ 1 - 1
transport/internet/kcp/segment.go

@@ -50,7 +50,7 @@ func NewDataSegment() *DataSegment {
 
 func (this *DataSegment) SetData(b []byte) {
 	if this.Data == nil {
-		this.Data = alloc.NewLocalBuffer(1600)
+		this.Data = alloc.NewSmallBuffer()
 	}
 	this.Data.Clear().Append(b)
 }

+ 1 - 3
transport/internet/udp/hub.go

@@ -74,7 +74,6 @@ type ListenOption struct {
 type UDPHub struct {
 	sync.RWMutex
 	conn   *net.UDPConn
-	pool   *alloc.BufferPool
 	cancel *signal.CancelSignal
 	queue  *UDPPayloadQueue
 	option ListenOption
@@ -105,7 +104,6 @@ func ListenUDP(address v2net.Address, port v2net.Port, option ListenOption) (*UD
 	}
 	hub := &UDPHub{
 		conn:   udpConn,
-		pool:   alloc.NewBufferPool(2048, 64),
 		queue:  NewUDPPayloadQueue(option),
 		option: option,
 		cancel: signal.NewCloseSignal(),
@@ -137,7 +135,7 @@ func (this *UDPHub) start() {
 
 	oobBytes := make([]byte, 256)
 	for this.Running() {
-		buffer := this.pool.Allocate()
+		buffer := alloc.NewSmallBuffer()
 		nBytes, noob, _, addr, err := ReadUDPMsg(this.conn, buffer.Value, oobBytes)
 		if err != nil {
 			log.Info("UDP|Hub: Failed to read UDP msg: ", err)