簡體   English   中英

如何優化此代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM