Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Proposed fix for #1183 - multiple regex within short time might give identical strings #1187
Proposed fix for #1183 - multiple regex within short time might give identical strings #1187
Changes from 3 commits
02f6b7c
66b75d7
04e0a62
62ef345
cc692c6
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
As per my knowledge
Random
is not thread safe. See e.g. here. Previously we created a random instance per request (probably internally within Xeger), so we didn't have that problem.Fixture by design can be used from multiple threads simultaneously, so we should take care of multi-threading.
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.
Ok, I'll look into it.
Should we use the code from https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomness/ ?
Basically doing
Xeger(pattern, ThreadLocalRandom.Instance)
This way we could abstract threadsafety concerns out of RegularExpressionGenerator... 🤔, and maybe reuse it elsewhere.
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.
@MagnusMikkelsen you can just follow the pattern used in all the other generators, e.g.
AutoFixture/Src/AutoFixture/RandomNumericSequenceGenerator.cs
Line 144 in d3e14a8
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.
@moodmosaic @MagnusMikkelsen If there is any way to do that without locks, please prefer that way. Introducing locking makes it hard to optimize performance later. When you have a bit suite, AutoFixture already takes substantial amount of time due to uncached reflection is uses everywhere - we shouldn't degrade it even more 😟
In this particular case, it might be better to abstract out random generation and create generator, which uses e.g.
Interlocked
. Or, for instance, create thread-local random, but use interlocked to generate seed.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.
Interlocked.CompareExchange or (IIRC) the Interlocked-extras by Jeffrey Richter in CLR via C# can be candidates.
Though right now, I’d suggest we stick with
lock
as done in all other places and be consistent.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.
Not sure how to use Interlocked.CompareExchange for this?
I did a couple of measurements, running the test below.
The times are measured using dotTrace, and are the total time and own time for
RegularExpressionGenerator.GenerateRegularExpression
.The last test (ThreadLocal) took 12s. Seems to make sense, given the
GenerateRegularExpression
used some 85 seconds in total on 8 threads.Random
Random
Random
each timelocking on generate seed
ThreadLocal
locking when generating
ThreadLocal
(It is beside the point of this PR - but the
Xeger.ctor
seems to take most of this time - 81000ms total time.Generate
is about 550ms total time. Might be an idea to cacheXeger
? Fxdictionary[pattern]=Xeger
)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.
Haven't got that book - so I don't know it, do you have any links with examples? I'd like to learn new tricks 😁