-
Notifications
You must be signed in to change notification settings - Fork 35
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
Proposal for generics-based Setter #201
base: master
Are you sure you want to change the base?
Conversation
Setter was never intended to be used in hot code paths, but if you can
achieve a performance improvement that would be very cool indeed.
I forked this project for my own uses so I could use `SetDefault()` without
any other external dependencies. If successful, it might also be
advantageous to make the change there as well.
https://github.com/kapetan-io/tackle
…On Wed, Sep 18, 2024, 11:06 AM medge ***@***.***> wrote:
Using generics, it should now be possible to achieve setter functionality
without reflection. If accepted: I can, either, add this to a /setter/v2
package or upgrade the existing methods.
Running on an M3 Macbook yields the following benchmark results:
go test -bench="BenchmarkSetter*" -benchmem -count=10 -tags holster_test_mode -run="^$" ./...
goos: darwin
goarch: arm64
pkg: github.com/mailgun/holster/v4/setter
BenchmarkSetterNew-12 <http://github.com/mailgun/holster/v4/setterBenchmarkSetterNew-12> 1000000000 0.9060 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9524 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9062 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9053 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9059 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9024 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9057 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9052 ns/op 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9054 ns/op. 0 B/op 0 allocs/op
BenchmarkSetterNew-12 1000000000 0.9056 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 210037180 5.647 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 213309236 5.626 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 210853106 5.648 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 211399341 5.635 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 213350558 5.690 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 213267204 5.671 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 210416016 5.672 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 210588644 5.678 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 210472189 5.790 ns/op 0 B/op 0 allocs/op
BenchmarkSetter-12 212123646 5.683 ns/op 0 B/op 0 allocs/op
------------------------------
You can view, comment on, or merge this pull request online at:
#201
Commit Summary
- dd8f762
<dd8f762>
Proposal for generics-based Setter
File Changes
(2 files <https://github.com/mailgun/holster/pull/201/files>)
- *M* setter/setter.go
<https://github.com/mailgun/holster/pull/201/files#diff-b82061095521d8fc5246208728c2f4c313fb1039f8764482ba7bfcea9406e948>
(15)
- *M* setter/setter_test.go
<https://github.com/mailgun/holster/pull/201/files#diff-8c99c56fa1594873d5407e231bfabc28ff5c33583dedb3843a77a23ba97c597a>
(109)
Patch Links:
- https://github.com/mailgun/holster/pull/201.patch
- https://github.com/mailgun/holster/pull/201.diff
—
Reply to this email directly, view it on GitHub
<#201>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAACMWMZVVNPMWZSWTEO2GDZXGQJ3AVCNFSM6AAAAABOOBEJVGVHI2DSMVQWIX3LMV43ASLTON2WKOZSGUZTIMJUGE3TSOA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
e9bbfd4
to
450a971
Compare
@thrawn01 good to know! The change was mostly intended to be a code reduction change vs. a performance improvement, for sure. The benchmark was added purely for curiosity's sake 🙏 |
70c7b5a
to
e107827
Compare
|
||
// IsZeroNew compares the given value to its Golang-specified zero value. | ||
// It works for any type T that satisfies comparable. | ||
func IsZeroNew[T comparable](value T) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be exportable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. The original method is both exported and used in a few libraries so that was the motivation, though I'm still pondering if it's needed 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to make it non-exportable and who needs could copy it as it's pretty small:
A little copying is better than a little dependency.
https://go-proverbs.github.io/
Well, I just don't like this name 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bahaha I don't like it either :D I'll leave the existing method (IsZero) exported and un-export this one, given the restricted use 👍
e107827
to
cdff537
Compare
assert.Equal(t, false, setter.IsZeroNew(thing)) | ||
} | ||
|
||
// Not possible now given compiler warnings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what Go version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point - this change would not work pre-Go generics, as far as I am aware. So Go 1.18+?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not running it in Go 1.18 - https://github.com/mailgun/holster/blob/master/.github/workflows/test.yaml#L19-L20
Are you seeing these warnings on your local env?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct. And that's why these tests are commented out. It's not possible to do what these tests did previously with the new methods. That's what its demonstrating 👀
Mind you, the name of the methods changed. I can fix that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And to be explicit: this test was previously trying to assign an int to a string, which you technically could do in the original method. The generics form doesn't allow that. It's a compilation error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And to be explicit: this test was previously trying to assign an int to a string, which you technically could do in the original method. The generics form doesn't allow that. It's a compilation error
I got it now.
Yeah, we don't need them at all, please remove the commented code. https://kentcdodds.com/blog/please-dont-commit-commented-out-code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, all that will be removed once we settle on the PR final form 👍 I just left them there as a note to reviewers!
cdff537
to
c99bf26
Compare
Using generics, it should now be possible to achieve
setter
functionality without reflection. If accepted, original methods will be marked as Deprecated but remain for existing usage.A major change here is that slices and maps do not work with the
setter.Default()
method.setter.Slice()
has been added thus far.setter.Map()
has proven interesting to do effectively and usage within Mailgun has not yet been found.Edit: while this was not done for performance reasons, rather as an attempt to simplify implementation code, here are the comparisons between approaches:
Running on an M3 Macbook yields the following benchmark results:
Updated benchmarks with a Slice test added: