I have a two foreach loops and need to replace with linq to overcome performance issues.
List<string> stringList = new List<string>();
foreach (var item in list)
{
foreach (var inneritem in item)
{
stringList.Add(inneritem.data1)
}
}
List<string> stringList = new List<string>();
foreach (var item in list)
{
foreach (var inneritem in item)
{
stringList.Add(inneritem.data1)
}
}
data1 string data is added to stringList.
LINQ will make the code cleaner, not faster. Inserting 1M items in a List will cause 20 reallocations and create 19 big temporary buffers if done carelessly.
Each time a list's internal buffer runs out, the List will create a new buffer twice as large and copy the old data over. The old buffer will remain in memory until the garbage collector runs. This can lead to a lot of big temporary buffers in memory and even an OutOfMemoryException if memory becomes so fragmented that .NET's allocator can't find a big enough memory range for a new buffer.
Cleaning up
One way is to use LINQ is to use two from
clauses :
var query = from item in list
from innerItem in item
select innerItem.data1;
var results=query.ToList();
Another way is to use SelectMany
to flatten a nested enumerable, eg :
var results = list.SelectMany(item=>item)
.Select(inner=>inner.data1)
.ToList();
Performance
To avoid reallocations, the list should be created in advance with a predefined capacity. The capacity doesn't have to be accurate.
If we expect eg 10K items, we can create a list with a capacity of 10K items and fill it in a loop:
var results=new List<string>(10000);
var query = from item in list
from innerItem in item
select innerItem.data1;
foreach(var item in query)
{
results.Add(item);
}
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