weightedrand icon indicating copy to clipboard operation
weightedrand copied to clipboard

Use of int for internal counter

Open cpacia opened this issue 2 years ago • 2 comments

Wouldn't it make more sense to use a uint64 for the total and max fields inside the chooser?

As it stands you allow the user to use a uint64 for the weight but the max weight total cannot exceed a maxInt. And that maxInt is different for users on 32 and 64 bit systems creating uncertainty in how the software will run on users computers.

I've had a bug report of my software being unable to run on 32 bit systems because I need the total weight to exceed a maxInt32 (and ideally maxInt64 for that matter).

It seems like if you're going to allow uint64s as weights then internally the counter should be able to handle that maximum value.

cpacia avatar Oct 20 '23 16:10 cpacia

I believe this would be possible now.

However, it would require a performance optimized version of sort.SearchInts that could handle uint64s (as per my benchmarks in mroth/xsort#1, the new slices.BinarySearch should be promising here once some nits are addressed in go1.22)

It would also require an implementation of rand.Uint64n, not currently in the standard library but should also be in go1.22 in the new math/rand/v2 module (also exists in the golang.org/exp/rand repo but I'd rather not pull in an exp dependency).

So the options would be to roll my own versions of the above functions (which makes me a little nervous, but is very feasible with enough testing -- I've definitely hit weird unexpected edge case bugs here in the past due to obscure int/uint behaviors so testing is required), or wait ~9mo and roll a v3 version of this library that requires >=go1.22. FWIW I already planned to do so upon release of go1.23 (I target at least stable and 'oldstable') in order to use the new math/rand/v2 which I'm quite excited about, so its a question of whether it's worth doing the work of a custom implementation for v2 of this library for the next N months.

Thoughts welcome. (I'm also curious what the use case is where you frequently need to be able to exceed maxInt64 with weights -- as I'm guessing a big.Int implementation is likely to have substantial performance hits.)

mroth avatar Oct 21 '23 14:10 mroth

Sounds good.

The use case i have is cryptocurrency related. The weight is a number of coins. The total coins on the network wont exceed MaxInt64 for 100 years so Int64 is fine, but in theory the number could go higher.

cpacia avatar Oct 21 '23 19:10 cpacia