Hi..
I couldn't resist to answer this :-)
The main reason your code gets slow, is that your items will be readed many many times. The art of speed is: Read memory only if you need to and if you need to read it, read it as less as possible.
Here is an example:
code
public class Item
{
private int _id;
private List<ItemDetails> _detailItems = new List<ItemDetails>();
public Item(int id)<br>
{
_id = id;
}
public void AddItemDetail(ItemDetails itemDetail)
{
_detailItems.Add(itemDetail);
}
public int Id
{
get { return _id; }
}
public ReadOnlyCollection<ItemDetails> DetailItems
{
get { return _detailItems.AsReadOnly(); }
}
}
public class ItemDetails
{
private int _parentId;
public ItemDetails(int parentId)
{
_parentId = parentId;
}
public int ParentId
{
get { return _parentId; }
}
}
example code:
The main goal is to scan the lists and compare the item and itemdetail on the current indexes. When the parentid is equal to it's parents id. add it to the list and go on to the next detail. If it is different go on to the next parent.
// for performance tests..
DateTime startDateTime;
// create 2 lists (master/child list)
List<Item> itemList = new List<Item>();
List<ItemDetails> itemDetailList = new List<ItemDetails>();
Debug.WriteLine("# Adding items");
startDateTime = DateTime.Now;
// add items (sorted)
for (int i = 0; i < 400000; i++)
itemList.Add(new Item(i));
// show how long it took
Debug.WriteLine("Total milliseconds: " + (DateTime.Now - startDateTime).TotalMilliseconds.ToString("0") + "ms" );
// adding some random details (also sorted)
Debug.WriteLine("# Adding itemdetails");
Random rnd = new Random(DateTime.Now.Millisecond);
startDateTime = DateTime.Now;
int index = 0;
for (int i = 0; i < 800000; i++)
{
// when the random number is bigger than 2, index will be increased by 1
index += rnd.Next(5) > 2 ? 1 : 0;
itemDetailList.Add(new ItemDetails(index));
}
Debug.WriteLine("Total milliseconds: " + (DateTime.Now - startDateTime).TotalMilliseconds.ToString("0") + "ms");
// show how many items the lists contains
Debug.WriteLine("ItemList Count: " + itemList.Count());
Debug.WriteLine("ItemDetailList Count: " + itemDetailList.Count());
// matching items
Debug.WriteLine("# Matching items");
startDateTime = DateTime.Now;
int itemIndex = 0;
int itemDetailIndex = 0;
int itemMaxIndex = itemList.Count;
int itemDetailMaxIndex = itemDetailList.Count;
// while we didn't reach any end of the lists, continue...
while ((itemIndex < itemMaxIndex) && (itemDetailIndex < itemDetailMaxIndex))
{
// if the detail.parentid matches the item.id. add it to the list.
if (itemList[itemIndex].Id == itemDetailList[itemDetailIndex].ParentId)
{
itemList[itemIndex].AddItemDetail(itemDetailList[itemDetailIndex]);
// increase the detail index.
itemDetailIndex++;
}
else
// the detail.parentid didn't matches the item.id so check the next 1
itemIndex++;
}
Debug.WriteLine("Total milliseconds: " + (DateTime.Now - startDateTime).TotalMilliseconds.ToString("0") + "ms");
results
I took 10 times more items to see a better result:
Adding items:
Total milliseconds: 140ms
Adding itemdetails:
Total milliseconds: 203ms
ItemList Count: 400000
ItemDetailList Count: 800000
Matching items:
Total milliseconds: 265ms
This was typed fast and could be cleaner. So i hope you can read it. Play with it.
Greetz,
Jeroen.