Я не удержался, чтобы ответить на это: -)
Основная причина, по которой ваш код работает медленно, заключается в том, что ваши элементы будут прочитаны много-много раз. Искусство скорости: читать память только, если вам нужно, и если вам нужно ее прочитать, читайте как можно меньше.
Вот пример:
код
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; }
}
}
пример кода:
Основная цель состоит в том, чтобы сканировать списки и сравнивать элемент и деталь по текущим индексам. Когда парентида равна его идентификатору родителей. добавьте его в список и переходите к следующей детали. Если это не так, переходите к следующему родителю.
// 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");
Результаты
Я взял в 10 раз больше предметов, чтобы увидеть лучший результат:
Добавление предметов:
Всего миллисекунд: 140 мс
Добавление товара:
Всего миллисекунд: 203 мс
ItemList Count: 400000
ItemDetailList Count: 800000
Подходящие предметы:
Всего миллисекунд: 265 мс
Это было напечатано быстро и может быть чище. Я надеюсь, что вы можете прочитать это. Играй с ним.
Greetz,
Йерун.