[英]What is the alternate way of using LINQ ForEach loop?
medicineList.ForEach(x =>
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
this.DrugItemsComboForSearch.Add(vm);
DoctorsOrderViewModel vm2 = new DoctorsOrderViewModel() { CategoryID = x.CategoryID, CategoryName = x.CategoryName, };
if (!this.MedicineCategoryItemsCombo.Select(y => y.CategoryID).Contains(x.CategoryID))
{
this.MedicineCategoryItemsCombo.Add(vm2);
}
});
在我的“ 13000醫學案例”中,此代碼花了8到10秒才能完成,但考慮到性能問題,時間太長。 我該如何優化呢?
使用LINQ ForEach循環的替代方法是什么?
一個標准的foreach
。
我該如何優化
至於性能,不是您的ForEach
就是問題,它可能是select
並contains
,考慮一次使用ToHashSet
var set = this.MedicineCategoryItemsCombo.Select(y => y.CategoryID).ToHashSet();
然后您可以在循環中使用
if (set.Add(x.CategoryID))
{
this.MedicineCategoryItemsCombo.Add(vm2);
}
但是,在閱讀代碼時,可以使用更好的查詢和Where
進行優化,然后執行Select
更新 :我花了一些時間,所以我可以寫一個完整的例子:
10x OPWay for 13000 medicines and 1000 categories: 00:00:03.8986663
10x MyWay for 13000 medicines and 1000 categories: 00:00:00.0879221
.Select
轉換后使用AddRange
Distinct
,而不是在每個循環中逐一掃描和添加。 public static List<(string catId, string catName)> MyWay(List<Medicine> medicineList)
{
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
var transformed = medicineList.Select(x =>
{
return new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
}).ToList(); ;
temp.AddRange(transformed);
DrugItemsComboForSearch.AddRange(transformed);
var MedicineCategoryItemsCombo = transformed.Select(m => (catId: m.CategoryID, catName: m.CategoryName)).Distinct().ToList();
return MedicineCategoryItemsCombo;
}
完整示例:
public static class MainClass
{
public class Medicine
{
public string PKID { get; set; }
public string Name { get; set; }
public string UnitName { get; set; }
public string CategoryID { get; set; }
public string CategoryName { get; set; }
public string DosageFormID { get; set; }
public string InventoryTypeID { get; set; }
}
public class DoctorsOrderViewModel
{
public string DrugID { get; set; }
public string Name { get; set; }
public string DrugName { get; set; }
public string UnitName { get; set; }
public string CategoryID { get; set; }
public string CategoryName { get; set; }
public string DosageFormID { get; set; }
public string InventoryTypeID { get; set; }
}
class Category
{
public string CategoryID { get; set; }
}
public static void Main()
{
var medicines = new List<Medicine>();
medicines.AddRange(Enumerable.Range(0, 13000).Select(i => new Medicine()
{
PKID = "PKID" + i,
Name = "Name" + i,
UnitName = "UnitName" + i,
CategoryID = "CategoryID" + i%1000,
CategoryName = "CategoryName for CategoryID" + i%1000,
DosageFormID = "DosageFormID" + i,
InventoryTypeID = "InventoryTypeID" + i,
}));
Stopwatch sw = new Stopwatch();
sw.Start();
List<DoctorsOrderViewModel> comboData = null;
for (int i = 0; i < 10; i++)
{
comboData = OpWay(medicines);
}
var elapsed = sw.Elapsed;
Console.WriteLine($"10x OPWay for {medicines.Count} medicines and {comboData.Count} categories: {elapsed}");
sw.Restart();
List<(string catId, string catName)> comboData2 = null;
for (int i = 0; i < 10; i++)
{
comboData2 = MyWay(medicines);
}
elapsed = sw.Elapsed;
Console.WriteLine($"10x MyWay for {medicines.Count} medicines and {comboData2.Count} categories: {elapsed}");
}
public static List<DoctorsOrderViewModel> OpWay(List<Medicine> medicineList)
{
List<DoctorsOrderViewModel> MedicineCategoryItemsCombo = new List<DoctorsOrderViewModel>();
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
medicineList.ForEach(x =>
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
DrugItemsComboForSearch.Add(vm);
DoctorsOrderViewModel vm2 = new DoctorsOrderViewModel() { CategoryID = x.CategoryID, CategoryName = x.CategoryName, };
if (!MedicineCategoryItemsCombo.Select(y => y.CategoryID).Contains(x.CategoryID))
{
MedicineCategoryItemsCombo.Add(vm2);
}
});
return MedicineCategoryItemsCombo;
}
public static List<(string catId, string catName)> MyWay(List<Medicine> medicineList)
{
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
var transformed = medicineList.Select(x =>
{
return new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
}).ToList(); ;
temp.AddRange(transformed);
DrugItemsComboForSearch.AddRange(transformed);
var MedicineCategoryItemsCombo = transformed.Select(m => (catId: m.CategoryID, catName: m.CategoryName)).Distinct().ToList();
return MedicineCategoryItemsCombo;
}
}
您可以對foreach
使用不同的方法,這比上面的方法更好,代碼也可以最小化:
foreach (Medicine medicine in medicineList)
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
this.DrugItemsComboForSearch.Add(vm);
if (!this.MedicineCategoryItemsCombo.Select(y => y.CategoryID ==
x.CategoryID).Any())
{
this.MedicineCategoryItemsCombo.Add(new DoctorsOrderViewModel()
{
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
};);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.