[英]How to optimize this code
它有一個屬性:字符串代碼和其他10個。
公共代碼是字符串列表(string [])汽車列表(Car [])filteredListOfCars是List。
for (int index = 0; index < cars.Length; index++)
{
Car car = cars[index];
if (commonCodes.Contains(car.Code))
{
filteredListOfCars.Add(car);
}
}
不幸的是,這片方法的時間太長了。
我有大約5萬條記錄
我怎樣才能降低執行時間?
最簡單的優化是將commonCodes從string[]
轉換為更快的查找結構,如Dictionary<string,object>
或HashSet<string>
如果您使用.Net 3.5或更高版本。 這將減少此循環的大O復雜性,並且取決於commonCodes的大小應該使此循環執行得更快。
Jared已正確指出您可以使用HashSet
進行優化,但我還想指出整個方法是不必要的,浪費了輸出列表的內存並使代碼不那么清晰。
您可以將整個方法編寫為:
var commonCodesLookup = new HashSet<int>(commonCodes);
var filteredCars = cars.Where(c => commonCodesLookup.Contains(c.Code));
在執行filteredCars
過濾操作將被推遲,因此,如果它的消費者只希望前10個元素,通過使用IE filteredCars.Take(10)
那么這並不需要建立整個列表(或任何列表所有)。
為了做你想做的事,我會使用Linq ToLookup方法創建一個ILookup而不是使用字典。 ToLookup特別適用於此類場景。 它基本上是對組進行索引查找。 您想按Code
對汽車進行分組。
var carCodeLookup = cars.ToLookup(car => car.Code);
carCodeLookup的創建速度很慢,但您可以根據Code
使用它來快速查找汽車。 要獲取公共代碼列表中的汽車列表,您可以快速查找。
var filteredCarsQuery = commonCodes.SelectMany(code => carCodeLookup[code]);
這假設您的汽車列表不會經常更改,並且您的commonCodes在查詢之間是動態的。
你可以使用linq join命令,比如
var filteredListOfCars = cars.Join(commonCodes, c => c.Code, cC => cC, (car, code) => car).ToArray();
這里是linq選項的替代品(也是好主意):如果你想快速過濾,我會建議利用內置類型。 您可以創建一個DataTable
,它有兩個字段,數組中汽車的id和代碼(如果它們也重要,您可以添加其他10個字段)。 然后你可以在它周圍創建一個DataView
並使用它的filter屬性。 它在內部使用了一些非常快速的索引(我相信B樹),所以你可能無法手動擊敗它的性能,除非你是一個算法高手,如果你是,你不會在這里問。 這取決於你正在做什么以及性能有多重要。
看起來你真正在檢查的是“代碼”是否常見,而不是汽車。 您可以考慮飛行重量模式,其中汽車共享代碼對象的常見實例。 然后,代碼對象可以具有IsCommon屬性和Value屬性。 然后,只要commoncodes列表發生更改,您就可以執行更新已使用的Code對象的操作。 現在,當您進行過濾時,您只需要檢查每個汽車代碼的IsCommon屬性
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.