-
Notifications
You must be signed in to change notification settings - Fork 62
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
Uniform integer/enum generation performance #363
Comments
This strikes me as a good addition (although I haven't thought about it carefully). Maybe @idontgetoutmuch or @turion would have opinions? |
Thanks for reporting this!
In principle that would be a good approach. But for backwards compatibility it should be a new class method, maybe
Yes, that would definitely be great! Another possibility might be a new class: class MonadDistribution m => MonadUniformRange m where
uniformR :: UniformRange a => a -> a -> m a Then this could be implemented for I'd welcome a PR for the second or the third variant! |
That sounds alarming and interesting 😅 if you can find the cause that would be very useful. How are you calling the final sampling effect? Are you using |
Is your feature request related to a problem? Please describe.
My model needs to generate 10⁸ uniform integers in a given range
[0; max)
(thinkmax ~ 1000
). The obvious way to useMonadDistribution
API seems to be something likefloor <$> uniform 0 max
. This works in roughly 7.7 s.I'm using
SamplerST
directly so I have the luxury to try outSamplerT $ ReaderT $ uniformRM (0, max - 1)
instead, and this works in roughly 0.3 s — more than 20x improvement!Moreover, in this case I don't even need to think whether I care about
uniform
ever returningmax
(which has probability 0 in ℝ but a non-zero, albeit small, probability in computer floats), which is an extra bonus.Describe the solution you'd like
Having a
randomInt
(and/orrandomIntegral
,randomEnum
and so on) inMonadDistribution
API that has a default implementation viauniform
but can be overriden (like inSampler
's case above) would perhaps be the most straightforward approach.I'd be more than happy to hack on this and open a PR if it's something that aligns with your vision, and I'm also open to any suggestions on the approach!
Describe alternatives you've considered
uniform
to operate on anyUniformRange a
instead of justDouble
s. This requires no changes to theSampler
instance which already usesuniformRM
under the hood, but I can't think off the top of my head how the default implementation (currently done viauniformDistr
) would need to be changed for an arbitraryUniformRange
.Additional context
As a side note, using
random
directly (as infloor . (* fromIntegral max) <$> random
) runs in about 0.75 s — about 10x faster thanuniform
, so I could also look at trying to improve that as well. Maybe it's just a fewINLINEABLE
s missing.The text was updated successfully, but these errors were encountered: