Generating Randomness

My new year’s resolution for this year was to not only start blogging more frequently but also to Open Source some of our core libraries that I’ve worked on over the years. In preparation for that though it’s important I cover some of the basics and explain the reasoning behind some of the code we’ll be putting out there.

I thought we’d start with something pretty easy, but hopefully with enough twist to interest more advanced readers. Today I’m starting with random number generation – or more precisely random stuff generation. This will form part of some future test code, but for now, I’d like to look at this small subset of the overall problem.

The first thing about the random generation in .NET is the System.Random class. Now, I’m assuming you’re mostly familiar with this little gem, but if not, here are some quick examples –

The important (and often missed) point of these examples is that the upper bound of the Next overloads is exclusive, that is it’s impossible to get Int32.MaxValue using the Next overload. Even worse, you can’t get any negative values. Similarly, NextDouble will only give you values greater than or equal to 0.0 or less than 1.0, which is hardly the whole range of possible doubles!

If we really want to be thinking about random number generation, the really useful method is the NextBytes method – and I’m going to flog it to death!

So first of all, what makes a good random ‘thing’ generator. Well priorities change based on application but at the top of my list is always “It must be theoretically possible to get every conceivable value” – this isn’t always achievable, but it’s the main goal for my implementations. After that, I normally place “It mustn’t be slow”, and finally, “Uniform distribution of values would be nice”. However, I don’t personally put uniformity ahead of performance.

I know in this regard I’m not going to get everyone’s agreement, however, in justification bare in mind that to actually get a random generator to give every possible long (by way of example) randomly would take so incredibly long that it’s uniformity is not that useful.

Ahead of everything, though, I want my Random number generators to be thread safe, and System.Random certainly isn’t (yet so many people miss that). The safest way to use a random is to declare a new one just before it’s use – but that creates a load of objects that need garbage collection. Way better is to have one Random per thread of execution – that way you don’t have to worry about locking, as a thread can’t interrupt itself.

Now achieving this scenario used to be a lot harder than it is in .NET 4 – now it’s easy –

The key here is the wonderful new System.Threading.ThreadLocal generic class. This allows us to create a field that has a different value on each thread (which is created by the lambda expression), so we can get a different Random on each thread – but only one per thread!

Now that I’ve solved thread safety let’s get on with creating our generators. For this, I want to add extension methods to the System.Random class, so I’m going to need a static class. to define them in (which in my project is called Tester as it’s part of my testing NuGet).

So let’s start with some easy ones –

These classes us our good old Random.Next to create simple types, being careful to remember that the upper bound is exclusive (and that chars are Unicode!). If you call the methods directly (i.e. not as extension methods) and pass in null, they will use the RandomGenerator defined above, otherwise you can specify your own Random object.

Now we can turn our attention to creating a random integer, that can have every possible value –

This method creates a 4-byte array and fills it with random bytes using the built-in random generator. Unlike Random.Next , it gives a uniform distribution of every possible Int32 value (including Int32.MaxValue and negatives).

We can extend the same principle to quite a few other types –

As you can see our new RandomDouble covers the whole double range, unlike Random.NextDouble() which is a nice result.

The next few types are going to get a little more tricky and require us to know something about their underlying implementations, for example, the decimal type. This can be constructed with four integers, but the last one is a bit special as it encodes a scale and a sign, and not all values are allowed (or possible) –

The first three integers are generated using our previous RandomInt32 method, but the last integer is calculated separately to ensure it’s always valid. We have to apply the same level of care to the DateTime generators –

These required a lot more thought but they’ve been thoroughly tested and checked, so feel free to use them even if the comments aren’t immediately transparent to you!

Finally, we probably want to be able to generate random strings –

The nullProbability allows you to optionally (and randomly) return nulls, and Unicode is likewise optional.

Next time, we’ll start looking at some more random generators related to SQL, but before we finish, how about something a bit different? The next two extensions are to the IEnumerable<T> interface, which extends the built-in LINQ queries to include a random item selector –

If you want any clarification, or you have a better implementation be sure to leave a comment! Once I get through these tutorials I’ll be sure to post the completed source.

Comments 2

Leave a Reply

%d bloggers like this: