Class Design Quality - c#

Is this class written by me is sufficient (I mean the way the pro's do it) to be included in a code/project? Or am I missing important things? I don't know how to use constructors etc so I did not use the same (I m just a beginner in C#) but please comment if so are required.
using System;
using System.Collections.Generic;
using System.Text;
namespace RandBit
{
/// <summary>
/// By: Author
/// Version 0.0.1
/// Pseudo-Random 16-Bit (Max) Generator.
/// </summary>
public class RandomBit
{
/// <param name="input">The Bit-size(int)</param>
/// <returns>Random Bit of Bit-size(string)</returns>
public static string Generate(int input)
{
int bitSize = 0;
Random choice = new Random();
if (input == 0 || input > 16)
{
bitSize = 0;
}
else if (input == 1)
{
bitSize = 1;
}
else
{
int randomChoice = choice.Next(0, (1 << input));
bitSize = randomChoice;
}
string binary = Convert.ToString(bitSize, 2);
binary = binary.PadLeft(input, '0');
return binary;
}
}
}
Thanks.

It appears that you are using Random incorrectly. I'd suggest starting with Jon Skeet's article on the subject. Relevant quote:
If you start off an instance of Random with the same initial state
(which can be provided via a seed) and make the same sequence of
method calls on it, you'll get the same results.
So what was wrong in our example code? We were using a new instance of
Random on each iteration of the loop. The parameterless constructor
for Random takes the current date and time as the seed - and you can
generally execute a fair amount of code before the internal timer
works out that the current date and time has changed. Therefore we're
using the same seed repeatedly - and getting the same results
repeatedly.
In other words, since you are creating a new instance of Random with each call, you are greatly increasing the chances that the return value won't be as "random" as you would expect.
It's also worth mentioning that there are potentially better PRNG classes already in the .Net BCL. Here's another way of writing similar code.
private static readonly RNGCryptoServiceProvider _crypto = new RNGCryptoServiceProvider();
public static long Generate(){
// use whatever size you want here; bigger has a better chance of
// being unique in a given scope
byte[] bytes = new byte[8];
// puts random bytes into the array
_crypto.GetBytes( bytes );
// do something (your choice) with the value...
return BitConverter.ToInt64( bytes, 0 );
}

You may only change one thing, since your class only contains a single static member, why don't make the class as static.

If I were the project team leader I would require that you drop summary/author/version comments. They are redundant (source control has that info), take a some time to write/modify and are ambiguous (in a file modified by 7 people who's the author?).
Here's a discussion on this topic, perhaps not the only one: https://softwareengineering.stackexchange.com/q/48562/30927

Move the variable "Choice" close to its usage i.e within the else loop.
Otherwise, You will be allocating un necessary memory to Random Object even if not used.
See here

Related

Why does ImmutableArray.Create copy an existing immutable array?

I am trying to make a slice of an existing ImmutableArray<T> in a method and thought I could use the construction method Create<T>(ImmutableArray<T> a, int offset, int count)like so:
var arr = ImmutableArray.Create('A', 'B', 'C', 'D');
var bc ImmutableArray.Create(arr, 1, 2);
I was hoping my two ImmutableArrays could share the underlying array here. But
when double checking this I see that the implementation doesn't:
From corefx/../ImmutableArray.cs at github at 15757a8 18 Mar 2017
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct.
/// </summary>
/// <param name="items">The array to initialize the array with.
/// The selected array segment may be copied into a new array.</param>
/// <param name="start">The index of the first element in the source array to include in the resulting array.</param>
/// <param name="length">The number of elements from the source array to include in the resulting array.</param>
/// <remarks>
/// This overload allows helper methods or custom builder classes to efficiently avoid paying a redundant
/// tax for copying an array when the new array is a segment of an existing array.
/// </remarks>
[Pure]
public static ImmutableArray<T> Create<T>(ImmutableArray<T> items, int start, int length)
{
Requires.Range(start >= 0 && start <= items.Length, nameof(start));
Requires.Range(length >= 0 && start + length <= items.Length, nameof(length));
if (length == 0)
{
return Create<T>();
}
if (start == 0 && length == items.Length)
{
return items;
}
var array = new T[length];
Array.Copy(items.array, start, array, 0, length);
return new ImmutableArray<T>(array);
}
Why does it have to make the copy of the underlying items here?
And isn't the documentation for this method misleading/wrong? It says
This overload allows helper methods or custom builder classes to
efficiently avoid paying a redundant tax for copying an array when the
new array is a segment of an existing array.
But the segment case is exactly when it copies, and it only avoids the copy if the desired slice is empty or the whole input array.
Is there another way of accomplishing what I want, short of implementing some kind of ImmutableArraySpan?
I'm going to answer my own question with the aid of the comments:
An ImmutableArray can't represent a slice of the underlying array because it doesn't have the fields for it - and obviously adding 64/128 bits of range fields that are only rarely used would be too wasteful.
So the only possibility is to have a proper Slice/Span struct, and there isn't one at the moment apart from ArraySegment (which can't use ImmutableArray as backing data).
It's probably easy to write an ImmutableArraySegment implementing IReadOnlyList<T> etc so will probably be the solution here.
Regarding the documentation - it's as correct as it can be, it avoids the few copies it can (all, none) and copies otherwise.
There are new APIs with the new Span and ReadonlySpan types which will ship with the magical language and runtime features for low level code (ref returns/locals).The types are actually already shipping as part of the System.Memory nuget package, but until they are integrated there will be no way of using them to solve the problem of slicing an ImmutableArray which requires this method on ImmutableArray (which is in System.Collections.Immutable that doesn't depend on System.Memory types, yet)
public ReadonlySpan<T> Slice(int start, int count)
I'm guessing/hoping such APIs will come once the types are in place.

how to avoid objects allocations? how to reuse objects instead of allocating them?

My financical software processes constantly almost the same objects. For example I have such data online:
HP 100 1
HP 100 2
HP 100.1 1
etc.
I've about 1000 updates every second.
Each update is stored in object - but i do not want to allocate these objects on the fly to improve latency.
I use objects only in short period of time - i recive them, apply and free. Once object is free it actually can be reused for another pack of data.
So I need some storage (likely ring-buffer) that allocates required number of objects once and them allow to "obtain" and "free" them. What is the best way to do that in c#?
Each object has id and i assign id's sequentially and free them sequentially too.
For example i receive id's 1 2 and 3, then I free 1, 2, 3. So any FIFO collection would work, but i'm looking for some library class that cover's required functionality.
I.e. I need FIFO collection that do not allocates objects, but reuse them and allows to reconfigure them.
upd
I've added my implementation of what I want. This is not tested code and probably has bugs.
Idea is simple. Writer should call Obtain Commit methods. Reader should call TryGet method. Reader and writer can access this structure from different threads:
public sealed class ArrayPool<T> where T : class
{
readonly T[] array;
private readonly uint MASK;
private volatile uint curWriteNum;
private volatile uint curReadNum;
public ArrayPool(uint length = 1024) // length must be power of 2
{
if (length <= 0) throw new ArgumentOutOfRangeException("length");
array = new T[length];
MASK = length - 1;
}
/// <summary>
/// TryGet() itself is not thread safe and should be called from one thread.
/// However TryGet() and Obtain/Commit can be called from different threads
/// </summary>
/// <returns></returns>
public T TryGet()
{
if (curReadNum == curWriteNum)
{
return null;
}
T result = array[curReadNum & MASK];
curReadNum++;
return result;
}
public T Obtain()
{
return array[curWriteNum & MASK];
}
public void Commit()
{
curWriteNum++;
}
}
Comments about my implementation are welcome and probably some library method can replace this simple class?
I don't think you should leap at this, as per my comments on the question - however, a simple approach would be something like:
public sealed class MicroPool<T> where T : class
{
readonly T[] array;
public MicroPool(int length = 10)
{
if (length <= 0) throw new ArgumentOutOfRangeException("length");
array = new T[length];
}
public T TryGet()
{
T item;
for (int i = 0; i < array.Length; i++)
{
if ((item = Interlocked.Exchange(ref array[i], null)) != null)
return item;
}
return null;
}
public void Recycle(T item)
{
if(item == null) return;
for (int i = 0; i < array.Length; i++)
{
if (Interlocked.CompareExchange(ref array[i], item, null) == null)
return;
}
using (item as IDisposable) { } // cleaup if needed
}
}
If the loads come in burst, you may be able to use the GC's latency modes to offset the overhead by delaying collects. This is not a silver bullet, but in some cases it can be very helpful.
I am not sure, if this is what you need, but you could always make a pool of objects that are going to be used. Initialize a List of the object type. Then when you need to use an object remove it from the list and add it back when you are done with it.
http://www.codeproject.com/Articles/20848/C-Object-Pooling Is a good start.
Hope I've helped even if a little :)
If you are just worried about the time taken for the GC to run, then don't be - it can't be beaten by anything you can do yourself.
However, if your objects' constructors do some work it might be quicker to cache them.
A fairly straightforward way to do this is to use a ConcurrentBag
Essentially what you do is to pre-populate it with a set of objects using ConcurrentBag.Add() (that is if you want - or you can start with it empty and let it grow).
Then when you need a new object you use ConcurrentBag.TryTake() to grab an object.
If TryTake() fails then you just create a new object and use that instead.
Regardless of whether you grabbed an object from the bag or created a new one, once you're done with it you just put that object back into the bag using ConcurrentBag.Add()
Generally your bag will get to a certain size but no larger (but you might want to instrument things just to check it).
In any case, I would always do some timings to see if changes like this actually make any difference. Unless the object constructors are doing a fair bit of work, chances are it won't make much difference.

Using clock ticks as random number seed

I'm using the current clock ticks as a seed for random number generation. The random number is used in a pseudo GUID and a check in my database will make sure it doesn't already exist before returning. On average, this method will be called around 10k times in succession during the life of the process.
My concern is that an identical number might be generated back to back resulting in multiple unnecessary recursive calls to my database checking for the same ID. I'd like to avoid this if possible. What is the best way to test this scenario?
If it matters, application is .NET 4 and database is SQL Server 2008.
private static string GenerateUniqueDelId()
{
// Generate a random integer using the current number of clock ticks as seed.
// Then prefix number with "DEL" and date, finally padding random integer with leading zeros for a fixed 25-character total length.
int seed = (int)DateTime.Now.Ticks;
Random number = new Random(seed);
string id = string.Format("DEL{0}{1}", DateTime.Today.ToString("yyyyMMdd"), number.Next().ToString("D14"));
// Lookup record with generated ID in Sesame. If one exists, call method recursively.
string query = "SELECT * FROM Lead WHERE Esm_Id = #Esm_Id";
SqlParameter[] parameters = { new SqlParameter("#Esm_Id", id) };
if (DataManager.GetRow(query, parameters, DelConnection.Sesame) != null) return GenerateUniqueDelId();
// Otherwise, return ID.
return id;
} //// End GenerateUniqueDelId()
You are right in your concern: You should move the creation of your Random instance out of your method body - otherwise you will re-seed with the same value many times which results in the same number sequence.
Also you are kinda re-inventing the wheel: the default constructor of the Random class already uses the current clock time as default seed.
The question is why don't you avoid all of this and just use an auto-generated Guid on the database side?
Quoting Jon Skeet
When you see the word "random" in a question title on Stack Overflow you can almost guarantee it will be the same fundamental problem as countless similar questions. This article takes a look at why randomness causes so many problems, and how to address them.
Check his article about random number generators
http://csharpindepth.com/Articles/Chapter12/Random.aspx
basically his solution looks like:
using System;
using System.Threading;
public static class RandomProvider
{
private static int seed = Environment.TickCount;
private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
new Random(Interlocked.Increment(ref seed))
);
public static Random GetThreadRandom()
{
return randomWrapper.Value;
}
}

Stack Overflow in random number generator

For some reason, this code works fine when I don't use a seed in the Random class, but if I try to use DateTime.Now to get a more random number, I get a StackOverflowException! My class is really simple. Could someone tell me what I'm doing wrong here? See MakeUniqueFileName.
public class TempUtil
{
private int strcmp(string s1, string s2)
{
try
{
for (int i = 0; i < s1.Length; i++)
if (s1[i] != s2[i]) return 0;
return 1;
}
catch (IndexOutOfRangeException)
{
return 0;
}
}
private int Uniqueness(object randomObj)
{
switch (randomObj.ToString())
{
case "System.Object":
case "System.String":
return randomObj.ToString()[0];
case "System.Int32":
return int.Parse(randomObj.ToString());
case "System.Boolean":
return strcmp(randomObj.ToString(), "True");
default:
return Uniqueness(randomObj.ToString());
}
}
public string MakeUniqueFileName()
{
return "C:\\windows\\temp\\" + new Random(Uniqueness(DateTime.Now)).NextDouble() + ".tmp";
}
}
You're calling DateTime.Now.ToString(), which doesn't give you one of the strings you're checking for... so you're recursing, calling it with the same string... which still isn't one of the strings you're looking for.
You don't need to use Random to demonstrate the problem. This will do it very easily:
Uniqueness(""); // Tick, tick, tick... stack overflow
What did you expect it to be doing? It's entirely unclear what your code is meant to be doing, but I suggest you ditch the Uniqueness method completely. In fact, I suggest you get rid of the whole class, and use Path.GetTempFileName instead.
In short:
It should say
switch (randomObj.GetType().ToString())
instead of
switch (randomObj.ToString())
But even then this isn't very clever.
You are passing a DateTime instance to your Uniqueness method.
This falls through and calls itself with ToString - on a DateTime instance this will be a formatted DateTime string (such as "21/01/2011 13:13:01").
Since this string doesn't match any of your switch cases (again), the method calls itself again, but the result of calling ToString on a string is the same string.
You have caused an infinite call stack that results in the StackOverflowException.
There is no need to call Uniquness - when creating a Random instance, it will be based on the current time anyways.
I suggest reading Random numbers from the C# in depth website.
The parameter-less constructor of Random already uses the current time as seed value. It uses the time ticks, used internally to represent a DateTime.
A problem with this approach, however, is that the time clock ticks very slowly compared to the CPU clock frequency. If you create a new instance of Random each time you need a random value, it may be, that the clock did not tick between two calls, thus generating the same random number twice.
You can simply solve this problem by creating a single instance of Random.
public class TempUtil {
private static readonly Random random = new Random();
public string MakeUniqueFileName()
{
return #"C:\windows\temp\" + random.NextDouble() + ".tmp";
}
}
This will generate very good random numbers.
By the way
System.IO.Path.GetTempFileName()
automatically creates an empty temporary file with a unique name and returns the full path of that file.
Where to begin.
1. There is already a string compare. Use it. It has been debugged.
2. Your Unique function is illogical. The first two case items return a 'S' perhaps cast to an int. You have neglected the break on the first case.
Your third case is like this:
if (x =="System.Int32") return int.Parse("System.Int32");
That may return 32, or a parse error.
Your fourth case is like this:
if (x == "System.Boolean") return strcmp("System.Boolean", "True");
Your default case is called recursevly (sp) causing the stack overflow (see comment above)
In order fix this program, I recommend you read at least one good book on C#, then rethink your program, then write it. Perhaps Javascript would be a better fit.

Random not working

To clarify, multiple students objects and all of them are getting the same value.
I know this question has been asked before, but I have had no luck with the other posts about his topic. I have a random number generator ranging from 1-3. I then us %2 to make a bool value true or false. Every time I run the program I either get all true or all false. Here is my code. I know that random is not really random. What can I do to get more random numbers.
Random random = new Random();
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
You are only assigning a random value to 'level' once during the constructor, so it will always have the initial value.
Try:
public bool readingLevel()
{
return (random.Next(1,3) % 2 == 0);
}
Edit:
Static Random random = new Random();
...
It looks like you're trying to get a random number!
Clippy
Well you can try something like this:
static Random random = new Random();
public Student()
{
lock (random)
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
The problem with your snippet seems to be that you are instantiating a new Random class with each of your class instances.
This is not the way Random is supposed to be used, but instead a single Random class instance should be used for acquiring multiple random numbers.
The Rationale for this is that Random in .Net uses a pseudo random algorithm based on state (a seed) that changes every time you ask for a new random number. By instantiating multiple random classes in a relatively short time span, there is a high chance that all of them will be initiated with the same seed (Based on system time) and all will give the same random number.
It looks like your random generator is an instance variable of the Student. Since the generator uses the current time as the seed, if you create a bunch of students within a short time, they will all have each have a generator with the same seed and the same results. You could make the random generator a static variable or, better yet, use constructor injection and pass the level into the Student's constructor.
class Student
{
private static Random random = new Random();
public Student()
{
level = random.NextDouble() < 0.5;
}
public bool readingLevel()
{
return level;
}
}
or use constructor injection so your student class is deterministic.
class Student
{
private boolean level;
public Student(boolean readingLevel)
{
this.level = readingLevel;
}
public boolean readingLevel()
{
return level;
}
}
Create only one instance of Random and reuse it. Creating multiple instances of random in quick succession seeds to the same value and thus leads to the same sequence.
If your code in single threaded you can simply use a static property to hold the instance of Random.
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.
http://msdn.microsoft.com/en-us/library/h343ddh9.aspx
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
seems very much like a constructor for the Student class. In this constructor you are basically calculating a random number and storing it inside the level field. So if you use the same instance of Student throughout your entire program and call the readingLevel() method multiple times on this instance it will obviously return the same value -> the one that was done during the construction of this instance and that you stored in the level field.
So you might consider moving the random number generation logic into the readingLevel() method instead of simply returning the same value over and over again:
public class Student
{
private Random random = new Random();
public bool readingLevel()
{
int randomLevel = random.Next(1,3);
return (randomLevel % 2 == 0);
}
}
Now everytime you call this method on the same instance you should get a new calculation of a random number.
Some others have said this, but I think the point deserves underscoring with an example.
public class Student
{
Random random = new Random();
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
}
public class Program
{
public static void Main()
{
var students = new List<Student>();
for (int i = 0; i < 10; i++)
students.Add(new Student());
//Now you have 10 Students; each Student has its own random number generator
//The generators were created within microseconds of each other, so they most likely have THE SAME SEED
//Because they have the same seed, they will generate identical sequences of numbers
//Each student's reading level is calculated from the first call to .Next(1, 3) on its own RNG.
//The RNGs have the same seed, so each will return the same value for the first call to .Next(1, 3)
//Therefore, all students will have the same reading level!
}
}
You are using random to simulate a true/false situation, so you are trying to limit the result to either 1 or 2. Given that you are doing an odd/even test on the result you might be better off doing:
int randomLevel = random.Next();
level = (randomLevel % 2 == 0);
Also If you create all your students in quick succession there's a good chance that your current code will return the same value for subsequent calls.
Well.
Consider what is happening here. When your Student is constructued, you get some random number, and then set it to the member variable level.
Then, at some other point, you call a function, readingLevel, which returns this previously set value.
Then, you may ponder to yourself: Exactly when would this function give a different value? Well, it will only do so when level gets a different value. And when does that happen? Well, it only happens in the constructor, so, that means, it never happens again for the life of the object ....
Try the following. Move the selection of the random level to the readingLevel function.
Random random = new Random();
public Student()
{
}
public bool readingLevel()//this always returns one value for the entire program.
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
return level;
}
That is because you are using the random.Next() and the level evaluation within the constructor of your class, remember that the constructor is only executed when you create a new instance of your object, for having it executed several times create a different method where you call the random and the level evaluation, that way you'll get different values every time or use Something like this:
public bool Level()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
return level;
}
Random random = new Random(DateTime.Now.Ticks);

Categories

Resources