Skip to content

Commit 33db173

Browse files
committed
Refactor pprof profile traversal
1 parent 725cfdd commit 33db173

File tree

5 files changed

+96
-41
lines changed

5 files changed

+96
-41
lines changed

pkg/convert/parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var _ = Describe("convert", func() {
2626
It("parses data correctly", func() {
2727
result := []string{}
2828

29-
b, err := ioutil.ReadFile("fixtures/cpu.pprof")
29+
b, err := ioutil.ReadFile("testdata/cpu.pprof")
3030
Expect(err).ToNot(HaveOccurred())
3131
r := bytes.NewReader(b)
3232
g, err := gzip.NewReader(r)

pkg/convert/profile-extensions.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

pkg/convert/profile_extra.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package convert
2+
3+
// These functions are kept separately as profile.pb.go is a generated file
4+
5+
import (
6+
"sort"
7+
8+
"github.com/valyala/bytebufferpool"
9+
)
10+
11+
func (x *Profile) Get(sampleType string, cb func(name []byte, val int)) error {
12+
valueIndex := 0
13+
if sampleType != "" {
14+
for i, v := range x.SampleType {
15+
if x.StringTable[v.Type] == sampleType {
16+
valueIndex = i
17+
break
18+
}
19+
}
20+
}
21+
22+
b := bytebufferpool.Get()
23+
for _, s := range x.Sample {
24+
for i := len(s.LocationId) - 1; i >= 0; i-- {
25+
name, ok := x.findFunctionName(s.LocationId[i])
26+
if !ok {
27+
continue
28+
}
29+
if b.Len() > 0 {
30+
_ = b.WriteByte(';')
31+
}
32+
_, _ = b.WriteString(name)
33+
}
34+
cb(b.Bytes(), int(s.Value[valueIndex]))
35+
b.Reset()
36+
}
37+
38+
bytebufferpool.Put(b)
39+
return nil
40+
}
41+
42+
func (x *Profile) findFunctionName(locId uint64) (string, bool) {
43+
if loc, ok := x.findLocation(locId); ok {
44+
if fn, ok := x.findFunction(loc.Line[0].FunctionId); ok {
45+
return x.StringTable[fn.Name], true
46+
}
47+
}
48+
return "", false
49+
}
50+
51+
func (x *Profile) findLocation(lid uint64) (*Location, bool) {
52+
idx := sort.Search(len(x.Location), func(i int) bool {
53+
return x.Location[i].Id >= lid
54+
})
55+
if idx < len(x.Location) {
56+
if l := x.Location[idx]; l.Id == lid {
57+
return l, true
58+
}
59+
}
60+
return nil, false
61+
}
62+
63+
func (x *Profile) findFunction(fid uint64) (*Function, bool) {
64+
idx := sort.Search(len(x.Function), func(i int) bool {
65+
return x.Function[i].Id >= fid
66+
})
67+
if idx < len(x.Function) {
68+
if f := x.Function[idx]; f.Id == fid {
69+
return f, true
70+
}
71+
}
72+
return nil, false
73+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package convert
2+
3+
import (
4+
"bytes"
5+
"compress/gzip"
6+
"io/ioutil"
7+
"testing"
8+
)
9+
10+
func BenchmarkProfile_Get(b *testing.B) {
11+
buf, _ := ioutil.ReadFile("testdata/cpu.pprof")
12+
g, _ := gzip.NewReader(bytes.NewReader(buf))
13+
p, _ := ParsePprof(g)
14+
noop := func(name []byte, val int) {}
15+
b.ResetTimer()
16+
17+
b.Run("ByteBufferPool", func(b *testing.B) {
18+
for i := 0; i < b.N; i++ {
19+
_ = p.Get("samples", noop)
20+
}
21+
})
22+
}
File renamed without changes.

0 commit comments

Comments
 (0)