patterncsharpModerate
Random string of variable length generator
Viewed 0 times
randomlengthgeneratorvariablestring
Problem
Below is my code for generating a random string of random length. I am using it in integration tests. Currently I have almost 2000 tests running each time a commit is made to master and a few of those tests are using this class.
I would like to make sure the code is optimized so that the tests complete as quickly as possible.
I would like to make sure the code is optimized so that the tests complete as quickly as possible.
public class Strings
{
private static readonly Random Random = new Random();
private static int RandomChar => Random.Next(char.MinValue, char.MaxValue);
public static string GenerateRandomStringOfSetLength(int length)
{
return GenerateRandomString(length);
}
private static string GenerateRandomString(int length)
{
var stringBuilder = new StringBuilder();
while (stringBuilder.Length - 1 <= length)
{
var character = Convert.ToChar(RandomChar);
if (!char.IsControl(character))
{
stringBuilder.Append(character);
}
}
return stringBuilder.ToString();
}
}Solution
Just two remarks:
In general, methods represent actions and properties represent data. Properties are meant to be used like fields, meaning that properties should not be computationally complex or produce side effects.
from Choosing Between Properties and Methods
so
Do use a property, rather than a method, if the value of the property is stored in the process memory and the property would just provide access to the value.
but
Do use a method, rather than a property, in the following situations.
amonong many others:
_
You can also improve the performance by precalculating the array with chars:
the
so building the string can be a simple loop:
Without the
Changing the
RandomCharshould be a method because it returns a different result each time - this is just a convention that we usually follow in C#
In general, methods represent actions and properties represent data. Properties are meant to be used like fields, meaning that properties should not be computationally complex or produce side effects.
from Choosing Between Properties and Methods
so
Do use a property, rather than a method, if the value of the property is stored in the process memory and the property would just provide access to the value.
but
Do use a method, rather than a property, in the following situations.
amonong many others:
- The operation returns a different result each time it is called, even if the parameters do not change. For example, the
NewGuidmethod returns a different value each time it is called.
- You can cast the result to
charand don't need theConvert.ToChar
_
private static char RandomChar() => (char)Random.Next(char.MinValue, char.MaxValue);You can also improve the performance by precalculating the array with chars:
private static readonly char[] Chars =
Enumerable
.Range(char.MinValue, char.MaxValue)
.Select(x => (char)x)
.Where(c => !char.IsControl(c))
.ToArray();the
RandomChar method would take the values from this array:private static char RandomChar() => Chars[Random.Next(0, Chars.Length)];so building the string can be a simple loop:
for (int i = 0; i < length; i++)
{
stringBuilder.Append(RandomChar());
}Without the
StringBuilder this seems to be faster in tests by just ~8ms for 100.000 loops and a string lenght of 1.000var chars = new char[length];
for (int i = 0; i < length; i++)
{
chars[i] = RandomChar();
}
return new string(chars);StringBuilder.ToString processes the data in order to build the string. It's quite fast but in this particular situation the minimal overhead is noticable. Generally the StringBuilder is the fastet way to build strings so using it is definitely the right choice.Changing the
Random.Next(0, max) to Random.Next(max) improves the performance by another 10ms for the same tests.Code Snippets
private static char RandomChar() => (char)Random.Next(char.MinValue, char.MaxValue);private static readonly char[] Chars =
Enumerable
.Range(char.MinValue, char.MaxValue)
.Select(x => (char)x)
.Where(c => !char.IsControl(c))
.ToArray();private static char RandomChar() => Chars[Random.Next(0, Chars.Length)];for (int i = 0; i < length; i++)
{
stringBuilder.Append(RandomChar());
}var chars = new char[length];
for (int i = 0; i < length; i++)
{
chars[i] = RandomChar();
}
return new string(chars);Context
StackExchange Code Review Q#152551, answer score: 16
Revisions (0)
No revisions yet.