瀏覽代碼

doc + micro optimization

Optimizations:
- one cmp less in loops (-> do while)
- optimized loops for branch prediction
Julien Schmidt 12 年之前
父節點
當前提交
e2532bacac
共有 1 個文件被更改,包括 13 次插入8 次删除
  1. 13 8
      buffer.go

+ 13 - 8
buffer.go

@@ -13,6 +13,8 @@ import "io"
 
 const defaultBufSize = 4096
 
+// A read buffer similar to bufio.Reader but zero-copy-ish
+// Also highly optimized for this particular use case.
 type buffer struct {
 	buf    []byte
 	rd     io.Reader
@@ -42,17 +44,15 @@ func (b *buffer) fill(need int) (err error) {
 	b.idx = 0
 
 	var n int
-	for b.length < need {
+	for {
 		n, err = b.rd.Read(b.buf[b.length:])
 		b.length += n
 
-		if err == nil {
+		if b.length < need && err == nil {
 			continue
 		}
 		return // err
 	}
-
-	return
 }
 
 // grow the buffer to at least the given size
@@ -60,17 +60,22 @@ func (b *buffer) fill(need int) (err error) {
 // https://groups.google.com/forum/#!topic/golang-nuts/ETbw1ECDgRs
 func (b *buffer) grow(size int) {
 	// If append would be too expensive, alloc a new slice
-	if size > 2*cap(b.buf) {
+	if size > cap(b.buf)*2 {
 		newBuf := make([]byte, size)
 		copy(newBuf, b.buf)
 		b.buf = newBuf
 		return
 	}
 
-	for cap(b.buf) < size {
-		b.buf = append(b.buf[:cap(b.buf)], 0)
+	for {
+		b.buf = append(b.buf, 0)
+		b.buf = b.buf[:cap(b.buf)]
+
+		if cap(b.buf) < size {
+			continue
+		}
+		return
 	}
-	b.buf = b.buf[:cap(b.buf)]
 }
 
 // returns next N bytes from buffer.