Просмотр исходного кода

Use bytes.Buffer pools for wrappers

tags/0.9
9seconds 7 лет назад
Родитель
Сommit
9ddf3e147c
2 измененных файлов: 39 добавлений и 12 удалений
  1. 27
    0
      wrappers/buffer_pool.go
  2. 12
    12
      wrappers/streamcipherrwc.go

+ 27
- 0
wrappers/buffer_pool.go Просмотреть файл

1
+package wrappers
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+var bufPool sync.Pool
9
+
10
+func getBuffer() *bytes.Buffer {
11
+	buf := bufPool.Get().(*bytes.Buffer)
12
+	buf.Reset()
13
+
14
+	return buf
15
+}
16
+
17
+func putBuffer(buf *bytes.Buffer) {
18
+	bufPool.Put(buf)
19
+}
20
+
21
+func init() {
22
+	bufPool = sync.Pool{
23
+		New: func() interface{} {
24
+			return &bytes.Buffer{}
25
+		},
26
+	}
27
+}

+ 12
- 12
wrappers/streamcipherrwc.go Просмотреть файл

22
 
22
 
23
 // Write writes into connection.
23
 // Write writes into connection.
24
 func (c *StreamCipherReadWriteCloser) Write(p []byte) (int, error) {
24
 func (c *StreamCipherReadWriteCloser) Write(p []byte) (int, error) {
25
-	encrypted := make([]byte, len(p))
25
+	// This is to decrease an amount of allocations. Unfortunately, escape
26
+	// analysis in (at least Golang 1.10) is absolutely not perfect. For
27
+	// example, it understands that we want to have a slice locally, right?
28
+	// But since slice is effectively 2 ints + uintptr to [number]byte, the
29
+	// most heavyweight part is placed in heap.
30
+	buf := getBuffer()
31
+	defer putBuffer(buf)
32
+	buf.Grow(len(p))
33
+	buf.Write(p)
34
+
35
+	encrypted := buf.Bytes()
26
 	c.encryptor.XORKeyStream(encrypted, p)
36
 	c.encryptor.XORKeyStream(encrypted, p)
27
-	allWritten := 0
28
-
29
-	for len(encrypted) > 0 {
30
-		n, err := c.conn.Write(encrypted)
31
-		allWritten += n
32
-		if err != nil {
33
-			return allWritten, err
34
-		}
35
-		encrypted = encrypted[n:]
36
-	}
37
 
37
 
38
-	return allWritten, nil
38
+	return c.conn.Write(encrypted)
39
 }
39
 }
40
 
40
 
41
 // Close closes underlying connection.
41
 // Close closes underlying connection.

Загрузка…
Отмена
Сохранить