-
Notifications
You must be signed in to change notification settings - Fork 2
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
Add sample_single to Range #69
Conversation
I am seeing some improvements in other benchmarks too: Before:
After:
|
Just added a little optimisation to
With |
Hmm, not sure how to answer this. I'm not so happy with the use of |
With For cryptographic RNG's generating Small fast RNG's mostly need to operate on 64-bit words for good statistical quality. There are some really fast ones where on x86_64 generating So on second thought using |
Now I wonder if the optimization of I do like that it removes a complex dependency between |
Yes, the optimisation/standalone impl for Not sure what you mean here?
|
It would be nice to have something like this as a default implementation: fn sample_single<R: Rng+?Sized>(low: Self::X, high: Self::X, rng: &mut R) -> Self::X {
let range: Self = RangeImpl::new(low, high);
range.sample(rng)
} Then we would not have to add this code when there is no faster / specialized method available for some type (like the one in the tests of this module). But I could not get it to work because Rust can't figure out the types (and neither could I...). |
Ah. It's actually quite simple:
What the compiler is saying is that you can only construct sized types; here you are trying to construct |
I can't really imagine a |
pub trait RangeImpl { | ||
/// The type sampled by this implementation (output type). | ||
pub trait RangeImpl: Sized { | ||
/// The type sampled by this implementation. | ||
type X: PartialOrd; |
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.
Why does this type have a PartialOrd
bound?
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.
Um... it might be to allow the low < high
check. You can try removing it if you like.
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.
Now that I looked a bit better at it, SampleRange
already has PartialOrd+Sized
as trait bounds, which takes care of the low < high
check. But the extra bound kind of makes sense: you can't speak about a range between two points if there is not some sort of order between the elements. I will leave it for now.
I think this is ready now |
Great, thanks! I'm going to assume that the sampling is correct; I glanced over the code but there's so many routines just for ranges now; then there are all the other distributions. I'm thinking an external tool to plot 10'000+ samples for visual inspection might be useful, plus some "synthetic tests" (checking a few inputs produce the expected values). |
Now that you mention it, I did not add any tests... The tests for |
No, properly testing distributions would appear to be much more difficult than writing the distribution code. |
Yes, I was thinking about that after your comment. A simple test could be to generate a lot of numbers, fill something like 256 buckets, and compare if they roughly follow the distribution. But that would only catch the worst errors. Shall I open an issue? |
As discussed in #68.
Benchmarks before (with
i128_support
):After:
And the normal code with a one-time set-up cost for comparison:
The performance of
sample_single
depends quite a bit on how close the range is to a power of two, but I have not investigated the details... Performance seems worth the extra method.I am not sure the order of arguments is the best choice, with
(low, high, rng)
. Would(rng, low, high)
be better?Also I tried to make
sample_single
have a default implementation, like inRangeFloat
, but couldn't get it to work.