-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
nsqd: replace util.UniqRands #1012
Conversation
|
internal/util/rand.go
Outdated
if len(nums) == l { | ||
goto exit | ||
} | ||
func UniqRands(count int, choiceCount int) []int { |
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 switches the order of the arguments, but the caller still uses the original argument order.
I see you don't like l
and n
and that's fair, they're not super clear. But I find "count" being in both of your argument names to be confusing. I think we can come up with better names. Here's a proposal (back in the original order): (quantity, maxval int)
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.
I accept your opinion, and I will fix it.
Since the default QueueScanSelectionCount is 20, I think the interesting benchmark cases are:
And you could put the little benchmark function in |
By the way, you can push updates to your branch, and the updates will show up in this pull request, so you don't have to close it and open a new one. |
@ploxiln please review |
internal/util/rand.go
Outdated
goto exit | ||
} | ||
func init() { | ||
rand.Seed(time.Now().UnixNano()) |
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.
The rand seed is set in apps/nsqd/nsqd.go
, so we should not do that here.
I think we don't need to set a "good" random seed for tests (and they will be somewhat more deterministic if we don't).
internal/util/rand.go
Outdated
for i := 0; i < quantity; i++ { | ||
idx = rand.Int()%maxval + i | ||
// swap | ||
swap(intSlice, i, idx) |
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.
I don't think it's worth both a comment and a function for this.
I would just put the line of code that does the swap here.
Thanks for the updates. @mreiferson I think this change is worth it because the old implementation could have occasionally (randomly) bad worst-case performance - it could get "unlucky" and not randomly pick the one remaining possibility for a while. So, where it is used, the less-than-optimal average performance is not a problem at all. But the on-rare-occasion-terrible performance is worrysome. This new algorithm will always take a deterministic bounded number of steps (and the average performance is also better). I had to tweak the benchmark to make it work with the old implementation, because the old implementation did not internally check for +++ b/internal/util/util_test.go
@@ -6,7 +6,7 @@ import (
func BenchmarkUniqRands20_5(b *testing.B) {
for i := 0; i < b.N; i++ { //use b.N for looping
- UniqRands(20, 5)
+ UniqRands(5, 5)
}
@@ -30,7 +30,7 @@ func TestUniqRands(t *testing.T) {
t.Errorf("error, expect:%v, got:%v\n", 3, len(x))
}
- x = UniqRands(10, 5)
+ x = UniqRands(5, 5)
if len(x) == 5 {
t.Logf("success, %v", x) And the results are similar to those posted above. Before:
After:
|
LGTM, I’ll leave it for plo to merge when ready. |
I screwed this up, sorry - I was trying to push one more commit to vearne's branch, but:
so I'll have to do it in another PR, incoming |
replaced with #1019 |
The performance of util.UniqRands is not good, I re-implemented