small buffer

pull/314/head
Darien Raymond 2016-11-21 22:08:34 +01:00
parent c041740940
commit 70c75038a2
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
8 changed files with 67 additions and 24 deletions

View File

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

View File

@ -11,6 +11,31 @@ type Pool interface {
Free(*Buffer) 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 { type BufferPool struct {
chain chan []byte chain chan []byte
allocator *sync.Pool allocator *sync.Pool
@ -55,14 +80,15 @@ const (
mediumBufferByteSize = 8 * 1024 mediumBufferByteSize = 8 * 1024
BufferSize = mediumBufferByteSize - defaultOffset BufferSize = mediumBufferByteSize - defaultOffset
largeBufferByteSize = 64 * 1024 smallBufferByteSize = 2 * 1024
LargeBufferSize = largeBufferByteSize - defaultOffset SmallBufferSize = smallBufferByteSize - defaultOffset
PoolSizeEnvKey = "v2ray.buffer.size" PoolSizeEnvKey = "v2ray.buffer.size"
) )
var ( var (
mediumPool *BufferPool mediumPool *BufferPool
smallPool = NewSyncPool(2048)
) )
func init() { func init() {

View File

@ -58,3 +58,31 @@ func TestBufferString(t *testing.T) {
buffer.AppendString("Test String") buffer.AppendString("Test String")
assert.String(buffer.String()).Equals("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()
}
}

View File

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

View File

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

View File

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

View File

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

View File

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