2015-08-22 350 views
-3

我一直在編寫一個程序,它有一個100,000個元素的列表,我必須處理具有不同條件的所有元素。這最多不需要太多時間3秒。在此之後,我有一個有效的條目列表和我的信號列表,其中有100000個元素。通常新的列表大小爲6K - 7K。主要問題是當我使用List.Remove函數或其他任何方式從100K元素中刪除無效元素時,它的速度太慢。列表花費的時間太多

請指導我是否應該使用其他任何東西,然後是LIST,或者我也可以使用此代碼做些事情。

我包括我試過的所有代碼。

for(int k = 0; k < initialList.Count;k++) 
{ 
    combo c = initialList.ElementAt(k); 
    if(invalidEntries.Contains(c)) 
    { 
     smartString.Append(c.number1.ToString()); 
     smartString.Append(c.number2.ToString()); 
     smartString.Append(c.number3.ToString()); 
     smartString.Append(c.number4.ToString()); 
     smartString.Append(c.number5.ToString()); 
     smartString.Append(" Sum : "); 
     smartString.Append(c.sum.ToString()); 
     smartString.AppendLine(); 
     InvalidCombo.AppendText(smartString.ToString()); 
     smartString.Clear(); 
    } 
    else 
    { 
     smartString.Append(c.number1.ToString()); 
     smartString.Append(c.number2.ToString()); 
     smartString.Append(c.number3.ToString()); 
     smartString.Append(c.number4.ToString()); 
     smartString.Append(c.number5.ToString()); 
     smartString.Append(" Sum : "); 
     smartString.Append(c.sum.ToString()); 
     smartString.AppendLine(); 

     validCombo.AppendText(smartString.ToString()); 
     smartString.Clear(); 
    } 
} 

而且

for(int k=0;k<100000;k++) 
{ 
    combo c = initialList.ElementAt(k); 
    if (!invalidEntries.Contains(c)) 
     validEntries.Add(c); 
} 

我也曾嘗試卸下襬臂的功能,但我認爲不能單把它。所以任何建議/解決方案?

+1

這是U/I組件還是集合?如果您試圖在U/I組件中顯示100K項目,也許您需要重新考慮您的設計? – OldProgrammer

+0

嘗試使用StringDictionary而不是列表,並讓程序在從字典中刪除項目時提供字典條目的關鍵字。字典比列表更容易搜索。 –

+0

@OldProgrammer是它的一個UI程序,但列表是在代碼中生成的。它是一個結構列表,結構有6個整數元素。在ui中顯示的時間不是,但在處理部分上面給出了 –

回答

1

我是struct s的大風扇,但是當你有一個struct像你這樣的工作,你必須非常小心。依賴於相等的方法(Contains,IndexOf,Remove)可能不起作用,因此不應使用。 HashSet<T>和相似。
最適合您的情況是將處理與移除相結合。並且從List<T>中刪除的最快方法是不使用它刪除相關項目(Remove/RemoveAt)的方法! :-)相反,通過將列表中應該保留的項目(以及它們的計數)保存在列表的開頭,然後使用RemoveRange方法來刪除列表末尾的不必要項目,可以「壓縮」列表。這是非常有效的,並避免使用「正常」列表刪除方法時發生的所有數據塊移動。這是根據你的結構定義的一個示例代碼:

public struct combo { public int number1; public int number2; public int number3; public int number4; public int number5; public int sum; public bool invalid; } 

void ProcessList(List<combo> list) 
{ 
    int count = 0; 
    for (int i = 0; i < list.Count; i++) 
    { 
     var item = list[i]; 
     ProcessItem(ref item); 
     if (!item.invalid) list[count++] = item; 
    } 
    list.RemoveRange(count, list.Count - count); 
} 

void ProcessItem(ref combo item) 
{ 
    // do the processing and set item.invalid=true/false 
} 

在你沒有變異的ProcessItem內的項目時,你可以刪除ref修改,更改返回類型bool並用它來控制是否項目應該從列表中刪除或不。

0

以下是使用HashSet的示例。它非常快。

using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var myInts = new HashSet<int>(); 
      for (var i = 0; i < 100000; i++) 
       myInts.Add(i); 

      myInts.Remove(62345); 
     } 
    } 
} 
+0

嘿,我認爲我誤解了你的代碼,它不是你遇到麻煩的整數,而是你正在使用的任何結構。雖然答案仍然相同,請使用HashSet 併爲T指定任何結構。 –