Explorar el Código

Use bytes.Buffer pools for wrappers

tags/0.9
9seconds hace 7 años
padre
commit
9ddf3e147c
Se han modificado 2 ficheros con 39 adiciones y 12 borrados
  1. 27
    0
      wrappers/buffer_pool.go
  2. 12
    12
      wrappers/streamcipherrwc.go

+ 27
- 0
wrappers/buffer_pool.go Ver fichero

@@ -0,0 +1,27 @@
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 Ver fichero

@@ -22,20 +22,20 @@ func (c *StreamCipherReadWriteCloser) Read(p []byte) (n int, err error) {
22 22
 
23 23
 // Write writes into connection.
24 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 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 41
 // Close closes underlying connection.

Loading…
Cancelar
Guardar