I have a part of code that operates on large arrays of double
(containing about 6000 elements at least) and executes several hundred times (usually 800) .
When I use standard loop, like that:
double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
singleRow = someObject.producesOutput();
//...
// do something with singleRow
// ...
}
The memory usage rises for about 40MB (from 40MB at the beggining of the loop, to the 80MB at the end).
When I force to use the garbage collector to execute at every iteration, the memory usage stays at the level of 40MB (the rise is unsignificant).
double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
singleRow = someObject.producesOutput();
//...
// do something with singleRow
// ...
GC.Collect()
}
But the execution time is 3 times longer! (it is crucial)
How can I force the C# to use the same area of memory instead of allocating new ones?
Note: I have the access to the code of someObject
class, so if it would be needed, I can change it.
Why are you allocating a large, empty singleRow
only to overwrite it? Maybe you should be passing the array in to have its values modified in place. This would allow you to reuse it.
double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
someObject.FillWithOutput(singleRow);
//...
// do something with singleRow
// ...
}
If the method sometimes fills less than 6000 elements, it could simply return the fill count. Alternately, you could use a List<double>
, which will allow resizing.
Make singleRow
a parameter and pass it in to the call to producesOutput
every time...
Basically your producesOutput
method is probably allocating a new array every time, and the re-assignment of singleRow
just marks the old memory as available to remove, but doesn't run the GC for performance reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With