Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit f9879dd

Browse files
authored
Merge pull request #578 from erizocosmico/perf/reduce-gc-press
packfile: improve performance a little by reducing gc pressure
2 parents 770800d + 6a46a7e commit f9879dd

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

plumbing/format/packfile/common.go

+8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package packfile
22

33
import (
4+
"bytes"
45
"io"
6+
"sync"
57

68
"gopkg.in/src-d/go-git.v4/plumbing/storer"
79
"gopkg.in/src-d/go-git.v4/utils/ioutil"
@@ -49,3 +51,9 @@ func writePackfileToObjectStorage(sw storer.PackfileWriter, packfile io.Reader)
4951
_, err = io.Copy(w, packfile)
5052
return err
5153
}
54+
55+
var bufPool = sync.Pool{
56+
New: func() interface{} {
57+
return bytes.NewBuffer(nil)
58+
},
59+
}

plumbing/format/packfile/decoder.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,8 @@ func (d *Decoder) fillRegularObjectContent(obj plumbing.EncodedObject) (uint32,
347347
}
348348

349349
func (d *Decoder) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plumbing.Hash) (uint32, error) {
350-
buf := bytes.NewBuffer(nil)
350+
buf := bufPool.Get().(*bytes.Buffer)
351+
buf.Reset()
351352
_, crc, err := d.s.NextObject(buf)
352353
if err != nil {
353354
return 0, err
@@ -364,6 +365,7 @@ func (d *Decoder) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plum
364365
obj.SetType(base.Type())
365366
err = ApplyDelta(obj, base, buf.Bytes())
366367
d.cachePut(obj)
368+
bufPool.Put(buf)
367369

368370
return crc, err
369371
}

plumbing/format/packfile/diff_delta.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, erro
6060

6161
// DiffDelta returns the delta that transforms src into tgt.
6262
func DiffDelta(src []byte, tgt []byte) []byte {
63-
buf := bytes.NewBuffer(nil)
63+
buf := bufPool.Get().(*bytes.Buffer)
64+
buf.Reset()
6465
buf.Write(deltaEncodeSize(len(src)))
6566
buf.Write(deltaEncodeSize(len(tgt)))
6667

6768
sindex := initMatch(src)
6869

69-
ibuf := bytes.NewBuffer(nil)
70+
ibuf := bufPool.Get().(*bytes.Buffer)
71+
ibuf.Reset()
7072
for i := 0; i < len(tgt); i++ {
7173
offset, l := findMatch(src, tgt, sindex, i)
7274

@@ -93,8 +95,12 @@ func DiffDelta(src []byte, tgt []byte) []byte {
9395
}
9496

9597
encodeInsertOperation(ibuf, buf)
98+
bytes := buf.Bytes()
99+
100+
bufPool.Put(buf)
101+
bufPool.Put(ibuf)
96102

97-
return buf.Bytes()
103+
return bytes
98104
}
99105

100106
func encodeInsertOperation(ibuf, buf *bytes.Buffer) {

plumbing/format/packfile/scanner.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"hash/crc32"
1010
"io"
1111
stdioutil "io/ioutil"
12+
"sync"
1213

1314
"gopkg.in/src-d/go-git.v4/plumbing"
1415
"gopkg.in/src-d/go-git.v4/utils/binary"
@@ -291,10 +292,18 @@ func (s *Scanner) copyObject(w io.Writer) (n int64, err error) {
291292
}
292293

293294
defer ioutil.CheckClose(s.zr, &err)
294-
n, err = io.Copy(w, s.zr)
295+
buf := byteSlicePool.Get().([]byte)
296+
n, err = io.CopyBuffer(w, s.zr, buf)
297+
byteSlicePool.Put(buf)
295298
return
296299
}
297300

301+
var byteSlicePool = sync.Pool{
302+
New: func() interface{} {
303+
return make([]byte, 32*1024)
304+
},
305+
}
306+
298307
// SeekFromStart sets a new offset from start, returns the old position before
299308
// the change.
300309
func (s *Scanner) SeekFromStart(offset int64) (previous int64, err error) {
@@ -324,7 +333,9 @@ func (s *Scanner) Checksum() (plumbing.Hash, error) {
324333

325334
// Close reads the reader until io.EOF
326335
func (s *Scanner) Close() error {
327-
_, err := io.Copy(stdioutil.Discard, s.r)
336+
buf := byteSlicePool.Get().([]byte)
337+
_, err := io.CopyBuffer(stdioutil.Discard, s.r, buf)
338+
byteSlicePool.Put(buf)
328339
return err
329340
}
330341

0 commit comments

Comments
 (0)