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

feat: Opt for concatenation instead of using fmt.Sprintf #2270

Merged
merged 5 commits into from
Aug 20, 2024

Conversation

moisesvega
Copy link
Contributor

@moisesvega moisesvega commented May 2, 2024

Summary

The procedure.ToName function, a frequently used pathway,
currently relies on fmt.Sprintf to merge strings.
However, this method could inadvertently cause additional
memory allocations. By directly concatenating these strings
instead of utilizing fmt and constructing a format template,
we can reduce unnecessary allocations.

This minor modification has the potential to enhance the
efficiency of this library for all users.

Benchmark strategy

The strategy involves generating a string for both
the serviceName and methodName, running a series of
benchmarks, and then comparing the results using benchstat.

before.txt

goos: darwin
goarch: arm64
pkg: go.uber.org/yarpc/pkg/procedure
BenchmarkToName-10      12544957                95.07 ns/op           96 B/op          3 allocs/op
PASS
ok      go.uber.org/yarpc/pkg/procedure 1.421s

after.txt

goos: darwin
goarch: arm64
pkg: go.uber.org/yarpc/pkg/procedure
BenchmarkToName-10      36751287                28.92 ns/op           64 B/op          1 allocs/op
PASS
ok      go.uber.org/yarpc/pkg/procedure 1.549s

Results

bechstat result after running it with
go test -bench=. -count=100

name       old time/op    new time/op    delta
ToName-10    95.4ns ± 3%    28.8ns ± 6%  -69.79%  (p=0.000 n=90+97)

name       old alloc/op   new alloc/op   delta
ToName-10     96.0B ± 0%     64.0B ± 0%  -33.33%  (p=0.000 n=100+100)

name       old allocs/op  new allocs/op  delta
ToName-10      3.00 ± 0%      1.00 ± 0%  -66.67%  (p=0.000 n=100+100)

@CLAassistant
Copy link

CLAassistant commented May 2, 2024

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ biosvs
❌ moisesvega
You have signed the CLA already but the status is still pending? Let us recheck it.

Comment on lines 61 to 63
{"StringsLength-10", 10},
{"StringsLength-100", 100},
{"StringsLength-1000", 1000},
Copy link

Choose a reason for hiding this comment

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

I think this is a bit flaky? With 10, we're likely just randomizing enough of the same stringsto get to "0" ? Otherwise the numbers don't seem to make sense.

name                          old allocs/op  new allocs/op  delta
ToName/StringsLength-10-10        3.00 ± 0%      0.00       -100.00%  (p=0.000 n=100+100)
ToName/StringsLength-100-10       3.00 ± 0%      1.00 ± 0%   -66.67%  (p=0.000 n=100+100)
ToName/StringsLength-1000-10      3.00 ± 0%      1.00 ± 0%   -66.67%  (p=0.000 n=100+100)

I would just put a single basic benchmark with a hardcoded value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I will update the benchmark strategy and revise the summary accordingly.

// ToName gets the procedure name we should use for a method
// with the given service name and method name.
func ToName(serviceName string, methodName string) string {
return fmt.Sprintf("%s::%s", serviceName, methodName)
return serviceName + _separator + methodName
Copy link

Choose a reason for hiding this comment

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

In general, isn't this fully pre-computable and cacheable at startup? All yarpc configuration is static, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that by pre-computing this information early and storing it in the client object, we might further reduce allocations. I'll investigate this possibility in a separate PR.

@biosvs biosvs added this to the v1.73.1 milestone Aug 16, 2024
@biosvs biosvs merged commit 1597f03 into yarpc:dev Aug 20, 2024
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants