I am trying to understand memory allocation and how we can reduce them.
I created the following long list for testing
var list = new List<int>(Enumerable.Range(0, 1_000_000).ToArray());
Then I looped through it and printed a string like this
for (var i = 0; i < list.Count; i++)
{
Console.WriteLine("Item # " + list[i]);
}
The previous loop generated over 2 million allocations. I believe that the line "Item # " + list[i]
generated 2 million allocations.
** Question 1**
Why would it allocate 2 million string in this case? Does list[i]
have to be stored in the heap as string which is 1 allocation and then the combined string in another allocation, thus 2 allocations per loop?
Next step I thought about using a string builder to reduce allocations
var builder = new StringBuilder();
for (var i = 0; i < list.Count; i++)
{
builder.Append("Item # ");
builder.Append(list[i]);
Console.WriteLine(builder.ToString());
builder.Clear();
}
The above code has 1 million allocations, which is half of the previous allocation.
But, that still a lot of allocations.
I know string are immutable objects in C# and each string has it's own allocation in the heap. But, is there a way we reuse memory allocations so that we can create 1 string, then reuse the same allocation inside that loop over and over? In my case, once I print the string, I no longer need it. It would be safe for me to reuse the same allocation and just update it's value.
** Question 2** Is it possible to re-use memory allocations to reduce the amount of allocations?
** Question 3** What other tricks can I try to improve my loop?
Console.Write("Item # "); Console.WriteLine(list[i]);
instead of concatenation and thus allocation? – TentationSpan
s could help... – YesmanSpan
to reduce allocations here? – Duong