Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse protobuf buffer to decrease memory use. #234

Merged
merged 3 commits into from
Aug 29, 2017

Conversation

cory-stripe
Copy link
Contributor

@cory-stripe cory-stripe commented Aug 25, 2017

Summary

Use a reusable buffer for unmarshaling spans.

Motivation

When inspecting the heap of a box with lots of spans, we noticed a lot of memory usage in decoding protobuf:

screenshot 2017-08-25 08 44 54

I did some digging and found that proto.Buffer can be reused. I wrote a benchmark that — with -benchmem turned on — yields this:

Without buffer reuse:
BenchmarkParseSSF-8 3000000 507 ns/op 384 B/op 3 allocs/op
With buffer reuse:
BenchmarkParseSSF-8 3000000 420 ns/op 176 B/op 2 allocs/op

Test plan

Existing tests? Maybe add one that verifies two subsequent calls to ParseSSF don't screw anything up?

Rollout/monitoring/revert plan

Test out in QA

r? @aditya-stripe

@stripe-ci
Copy link

Gerald Rule: Copy Observability on Veneur and Unilog pull requests

cc @stripe/observability
cc @stripe/observability-stripe

parser_test.go Outdated
@@ -414,3 +414,14 @@ func TestServiceCheckMessageUnescape(t *testing.T) {
assert.NoError(t, err, "Should have parsed correctly")
assert.Equal(t, "foo\nbar\nbaz\n", svcheck.Message, "Should contain newline")
}

func BenchmarkParseSSF(b *testing.B) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hooray for adding a benchmark function!

@@ -43,6 +43,9 @@ type MetricKey struct {
JoinedTags string `json:"tagstring"` // tags in deterministic order, joined with commas
}

// A reusable protobuf buffer, is not safe to use concurrently!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it's not exported, but can we stick to godoc style for comments? (That is: // scratchBuff is a reusable protobuf buffer. It is not safe to share between goroutines).

@ChimeraCoder
Copy link
Contributor

Yeah, let's definitely add a test for multiple calls to ParseSSF with the same buffer.

@cory-stripe
Copy link
Contributor Author

Added!

@ChimeraCoder
Copy link
Contributor

lgtm!

@@ -84,7 +89,10 @@ func ValidMetric(sample *UDPMetric) bool {
// It also validates packets before returning them.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a note that this function isn't safe to use concurrently?

@cory-stripe
Copy link
Contributor Author

re-approving for rebase

@cory-stripe cory-stripe merged commit 26f6de2 into master Aug 29, 2017
@cory-stripe cory-stripe deleted the cory-reuse-gogo-buffer branch August 29, 2017 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants