[
https://issues.apache.org/jira/browse/RNG-78?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16782875#comment-16782875
]
Alex D Herbert commented on RNG-78:
-----------------------------------
I have created an initial implementation.
The factory method does not accept arguments for the {{RandomSource}}. This is
because the first call to create the random generator will fix the arguments.
Subsequent calls with different arguments cannot be supported as only one
generator is stored per enum value. So the simplest solution is to not support
this for generators that have arguments. This is current only
{{TWO_CMRES_SELECT}}.
I added a benchmark that simulates a worst case scenario for short lifetime
generators. It uses JMH to run threads in parallel to create a generator and
then produce numbers. I have some results for an easy to construct SPLIT_MIX
and a harder to construct MWC_256. The generators were used to create {{long}}
values.
For reference I have compared to {{ThreadLocalRandom}} which is an
implementation of the same SplitMix64 algorithm introduced in JDK 1.7. Here are
the test methods:
* threadLocalRandom: Use {{ThreadLocalRandom.current()}}
* threadLocalRandomWrapped: Wrap {{ThreadLocalRandom.current()}} with the
{{UniformRandomProvider}} interface
* randomSourceCreate: Create a new generator using {{RandomSource.create}}
* threadLocalRandomSourceCurrent: Use the new
{{ThreadLocalRandomSource.current()}} method
Run using 4 threads:
||numValues||randomSourceName||Method||Score||Relative||
|1|MWC_256|randomSourceCreate|26.1|5825.89|
|1|SPLIT_MIX_64|randomSourceCreate|0.798|178.13|
|1|N/A|threadLocalRandom|0.00448|1.00|
|1|N/A|threadLocalRandomWrapped|0.0045|1.00|
|1|MWC_256|threadLocalRandomSourceCurrent|0.0131|2.92|
|1|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.00977|2.18|
|10|MWC_256|randomSourceCreate|27|1467.39|
|10|SPLIT_MIX_64|randomSourceCreate|0.791|42.99|
|10|N/A|threadLocalRandom|0.0184|1.00|
|10|N/A|threadLocalRandomWrapped|0.0208|1.13|
|10|MWC_256|threadLocalRandomSourceCurrent|0.0594|3.23|
|10|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.0294|1.60|
|100|MWC_256|randomSourceCreate|26.6|170.51|
|100|SPLIT_MIX_64|randomSourceCreate|0.818|5.24|
|100|N/A|threadLocalRandom|0.156|1.00|
|100|N/A|threadLocalRandomWrapped|0.197|1.26|
|100|MWC_256|threadLocalRandomSourceCurrent|0.475|3.04|
|100|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.162|1.04|
Creating a new generator each time is slow.
ThreadLocalRandom is fastest. But then has to be wrapped if it is to be used
for any class that requires a UniformRandomProvider.
Once 10 samples are required for the short lived generator the new
{{ThreadLocalRandomSource}} is performing well, and once 100 samples are
required then the wrapped {{ThreadLocalRandom}} is outperformed by the
thread-local {{SplitMix}}.
I am not sure of the slow time for the {{MWC_256}} when used thread-locally.
The user guide timings indicate that this should be about 1.5x slower than
SplitMix for generation of {{long}} values. However I did not use a
{{BlackHole}} to consume values and just returned the combination of all values
using {{xor}}.
I will try some more generators, longer generation sequences, using a
{{BlackHole}} and another machine. However I believe the new class achieves the
aim of making local thread-safe short lived generators readily available.
Code can be inspected in [PR 27|https://github.com/apache/commons-rng/pull/27].
> ThreadLocalRandomSource
> -----------------------
>
> Key: RNG-78
> URL: https://issues.apache.org/jira/browse/RNG-78
> Project: Commons RNG
> Issue Type: New Feature
> Components: simple
> Affects Versions: 1.3
> Reporter: Alex D Herbert
> Assignee: Alex D Herbert
> Priority: Minor
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Implement a helper class that can provide thread-local
> {{UniformRandomProvider}} instances.
> This can be used as an equivalent of {{ThreadLocalRandom}}:
> {code:java}
> // c.f.
> Random random = ThreadLocalRandom.current();
> // Access a thread-safe random number generator
> UniformRandomProvider rng =
> ThreadLocalRandomSource.current(RandomSource.SPLIT_MIX_64);
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)