Skip to content

Commit c555934

Browse files
pymqthepudds
authored andcommitted
internal/profile: optimize Parse allocs
In our case, it greatly improves the performance of continuously collecting diff profiles from the net/http/pprof endpoint, such as /debug/pprof/allocs?seconds=30. This CL is a cherry-pick of my PR upstream: google/pprof#951 Benchmark of profile Parse func: goos: linux goarch: amd64 pkg: github.com/google/pprof/profile cpu: 13th Gen Intel(R) Core(TM) i7-1360P │ old-parse.txt │ new-parse.txt │ │ sec/op │ sec/op vs base │ Parse-16 62.07m ± 13% 55.54m ± 13% -10.52% (p=0.035 n=10) │ old-parse.txt │ new-parse.txt │ │ B/op │ B/op vs base │ Parse-16 47.56Mi ± 0% 41.09Mi ± 0% -13.59% (p=0.000 n=10) │ old-parse.txt │ new-parse.txt │ │ allocs/op │ allocs/op vs base │ Parse-16 272.9k ± 0% 175.8k ± 0% -35.58% (p=0.000 n=10) Change-Id: I737ff9b9f815fdc56bc3b5743403717c4b6f07fd GitHub-Last-Rev: a09108f GitHub-Pull-Request: #76145 Reviewed-on: https://go-review.googlesource.com/c/go/+/717081 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Florian Lehner <lehner.florian86@gmail.com>
1 parent 5132158 commit c555934

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/internal/profile/proto.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ package profile
2424
import (
2525
"errors"
2626
"fmt"
27+
"slices"
2728
)
2829

2930
type buffer struct {
@@ -175,6 +176,16 @@ func le32(p []byte) uint32 {
175176
return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
176177
}
177178

179+
func peekNumVarints(data []byte) (numVarints int) {
180+
for ; len(data) > 0; numVarints++ {
181+
var err error
182+
if _, data, err = decodeVarint(data); err != nil {
183+
break
184+
}
185+
}
186+
return numVarints
187+
}
188+
178189
func decodeVarint(data []byte) (uint64, []byte, error) {
179190
var i int
180191
var u uint64
@@ -275,6 +286,9 @@ func decodeInt64(b *buffer, x *int64) error {
275286
func decodeInt64s(b *buffer, x *[]int64) error {
276287
if b.typ == 2 {
277288
// Packed encoding
289+
dataLen := peekNumVarints(b.data)
290+
*x = slices.Grow(*x, dataLen)
291+
278292
data := b.data
279293
for len(data) > 0 {
280294
var u uint64
@@ -305,8 +319,11 @@ func decodeUint64(b *buffer, x *uint64) error {
305319

306320
func decodeUint64s(b *buffer, x *[]uint64) error {
307321
if b.typ == 2 {
308-
data := b.data
309322
// Packed encoding
323+
dataLen := peekNumVarints(b.data)
324+
*x = slices.Grow(*x, dataLen)
325+
326+
data := b.data
310327
for len(data) > 0 {
311328
var u uint64
312329
var err error

0 commit comments

Comments
 (0)