[
https://issues.apache.org/jira/browse/RNG-104?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16857597#comment-16857597
]
Alex D Herbert commented on RNG-104:
------------------------------------
I tried a few variants using ThreadLocal<>:
||Name||Implementation||Notes||
|ThreadLocalRNG|ThreadLocal<UniformRandomProvider>|Holds a SplitMix64 but named
using the interface to make it easy to switch the provider|
|ThreadLocalSplitMix|ThreadLocal<SplitMix64>| |
|ThreadLocalSequenceMix|ThreadLocal<long[]>|A single long value in an array so
it is mutable. This is the state of a SplitMix algorithm but is incremented and
mixed outside the ThreadLocal code.|
Here are some results just for int generation on 1 or 4 threads:
||Method||1||4||
|ThreadLocalRandom_nextInt|3.49|4.50|
|ThreadLocalSplitMix_nextInt|6.18|35.86|
|ThreadLocalRNG_nextInt|6.44|28.12|
|ThreadLocalSequenceMix_nextInt|6.57|29.90|
|Random_nextInt|9.68|321.56|
|System_identityHashCode|38.70|41.50|
ThreadLocalRandom wins.
Each ThreadLocal<> method is about the same. I do see some timing fluctuations
so will have to repeat this with more runs.
java.util.Random is very slow when there is thread contention.
The identity hash code method is slow on a single thread but largely unaffected
by thread contention.
*More on ThreadLocalRandom*
ThreadLocalRandom has dedicated fields that are declared in the Thread class.
It queries these using the sun.misc.Unsafe class. It has 3 fields. One to
indicate if the ThreadLocalRandom has been initialised. This is an int and is
read for each call to ThreadLocalRandom.current(). The second is a long which
is the state of the generator. This is read and set per call for a generation
of a random deviate. The third is for an internal faster random generator. It
does not affect public methods.
The ThreadLocal<> uses a map for each thread to store the items associated with
them. Each call has to query this map. If present the object is returned. So
the overhead of querying the map in the thread rather than directly accessing
thread variables is the difference.
*Conclusion*
Use of a ThreadLocal<SplitMix64> would outperform using the
System.identityHashCode method and would be more random as the hash code does
not generate negative values.
It would improve the speed of the SeedFactory and still maintain the intention
of using System.identityHashCode which is to increase the quality of the long
period generator.
> SeedFactory seed creation performance analysis
> ----------------------------------------------
>
> Key: RNG-104
> URL: https://issues.apache.org/jira/browse/RNG-104
> Project: Commons RNG
> Issue Type: Task
> Components: simple
> Affects Versions: 1.3
> Reporter: Alex D Herbert
> Assignee: Alex D Herbert
> Priority: Minor
>
> The SeedFactory is used to create seeds for the random generators. To ensure
> thread safety this uses synchronized blocks around a single generator. The
> current method only generates a single int or long per synchronisation.
> Analyze the performance of this approach. The analysis will investigate
> generating multiple values inside each synchronisation around the generator.
> This analysis will also investigate methods to supplement the SeedFactory
> with fast methods to create seeds. This will use a fast seeding method to
> generate a single long value. This can be a seed for a SplitMix generator
> used to create a seed of any length.
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)