Joe Developer is working with a simple struct:
Joe's tech lead asked him to write a method that will return an array of 10,000 initialized points. Joe wrote following code.
The code doesn't create any runtime errors, but Joe is worried because his tech lead looked at the code and frowned. What could provoke such a reaction?
Hint: Joe's lead is a performance nut.
Comments
The declaration:
Point[] points = new Point[10000];
will call the default ctor.
Because Point is a struct, it's a valuetype, which means it ALWAYS exist, it doesn't need to be new'ed.
As a result, all he needed was:
Point[] points = new Point[10000];
return points;
Point[] CreatePoints()
{
return new Point[10000];
}
So, maybe:
void CreatePoints(out Point[] result)
{
result = new Point[10000];
for (int i = 0; i < points.Length; i++)
{
result[i] = new Point();
}
}
Although, it takes 10 000 000 points in the array to waist 125 ms on my system.
array of points gets created on the heap.
new Point() creates a value type on the stack.
points[i]=... copies the Point from the stack to the heap.
better: return new Point[10000]; // done.
Point is a value type, so the new Point[10000] will actually allocate them all and set their x and y fields to 0. Then, the for loop allocates and initialializes them again, unnecessarily.
So, you're wasting valuable CPU time, causing the GC to have a minor anurism and ultimately using more electricity, therefore hurting the environment.
No sir, I don't like it!
-- Mr. Horse (from Ren & Stimpy)
Why use the for?
The simple fact that the Joe’s Developer as created the array of Point structs, doesn't required him to create each of the Points. This is because the compiler already allocates the necessary space to accommodate the structs. This, however, didn't work if the Point object was a class. In that case it was necessary to create each of the point objects.
This is basically the biggest difference between a class and a struct?
Am I correct?
Regards
Point[] points = new Point[10000];
does not just allocate space for an array of pointers to points, it actually allocates the space for them. The loop and subsequent allocations are unnecessary.
Since the point is a struct (=value type) Joe could create one new Point() before the start of the loop and asign it to every point in the array. Since it's a value type the Point will be copied to the array.
Cheers,
Wes
Cheers,
Wes
The developper did that because when initializing a struct on the stack, it's not automatically filled with 0's (contrary to reference types), so you have to call at least the parameterless constructor to initialize it.
:)
A lot of people pointed out that the for loop isn't needed. Since Point is a struct (a value type), creating the array is enough to give us 10,000 zero-initialized points.
The array is created on the heap, so it is ok to return a reference to the calling method.
Perhaps Gaptcha is better than what I was using. I'll have to give it a look.
finally, I have finished reading the 33 comments above.
Guys, look at the hint from the author. Regardless of whether or not you want to do a loop for initialization, just say we want to do the loop, then 10,000 would make a performance nut really goes nut.
However, against the author's intention, I would not be thinking about making the looping any faster, but to asynchronously do the loop on another thread and go do something else.
Hi Geoff, how are you?
It does however, make sense, especially on complex projects, to make the first write of the code as clear as possible (as this is), with little regard to performance, and then increase performance as needed.
Code "sevicablility" is a paramount issue to support people, however, lack of clarity as we all know, adds to R&D job security.
Performance, unfortunately, often goes hand-in-hand with lack of clarity.
Point[] CreatePoints()
{
Point[] points = new Point[10000];
int length = points.Length;
for (int i = 0; i < length; i++)
{
points[i] = new Point();
}
return points;
}