2016-08-23 46 views
1

我有一個數據表,包括超過300.000記錄,這等於超過2.000.000字。我有一個算法,可以從每個記錄中獲取所有單詞,並且運行良好,但我感覺它看起來很慢。C#數據表過濾器最快的方式

我想加快這個程序。

程序就像那樣;

  1. 從數據庫獲取所有記錄到數據表。
  2. 循環數據表並從每條記錄中獲取所有單詞。
  3. 對於每個單詞檢查新數據表包含該單詞,如果沒有添加到新的數據表。

我搜索了一些關於加速這個程序的標題。

  1. 使用foreach還是for? (我想,沒有區別)
  2. 檢查表具有文字或不使用DataTable.Select()或LINQ(LINQ的實際速度更快)

但我擔心的是檢查每個字包含或使一個字段的字段爲主(我不知道它是否有效),或者在沒有檢查的情況下獲取所有字,並且在使用distinc之後完成所有的字詞。

你可以給我一些建議。謝謝。

 DataTable dtProducts = getProducts(); 
     bool contains; 
     string[] keys; 

     dt.Columns.Add("keyword", typeof(string)); 

     for (int i = 0; i < dtProducts.Rows.Count; i++) //114040 
     { 
      keys = GetWords(dtProducts.Rows[i]["name"].ToString().Trim()); 

      foreach (string key in keys) 
      { 
       DataRow dr = dt.NewRow(); 
       dr["keyword"] = key; 

       contains = dt.AsEnumerable().Any(row => key == row.Field<string>("keyword")); 

       if (!contains) 
       { 
        dt.Rows.Add(dr); 
       } 
      } 
     } 
+0

你可以顯示一些你使用的代碼,它會讓你更容易給你一些提示。 –

+1

你使用'DataTable'開始的任何原因?這聽起來像你應該只使用一個'HashSet '並且在沒有'DataTable'妨礙的情況下從數據庫中讀取時添加它。 –

+5

可能最有效的方法是在數據庫中進行篩選,而不是先將所有內容加載到內存中。 –

回答

4

可能最有效的方法是在數據庫中進行過濾,而不是先將所有內容加載到內存中。但是你也可以不加載所有進入DataTable提高性能,但如果使用SqlDataReaderHashSet<string>代替:

private static readonly char[] WordSeparator = { ' ', '\t', ',', '.', ':' }; // to be continued 
// .... 


HashSet<string> allUniqueWords = new HashSet<string>(); 
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString)) 
using (var cmd = new SqlCommand("SELECT DISTINCT ColumnName FROM dbo.TableName", con)) 
{ 
    con.Open(); 
    using (var rd = cmd.ExecuteReader()) 
    { 
     string[] words = rd.GetString(0).Split(WordSeparator, StringSplitOptions.RemoveEmptyEntries); 
     foreach (string word in words) 
      allUniqueWords.Add(word); 
    } 
} 
+0

謝謝先生:) –

0

由於新添加的單詞和它們未被排序,您的軟件將呈指數級慢,所以它會遍歷所有記錄中的每個單詞。

一個基本的事情就是讓你的Datatable到一個List並將這些單詞插入List中。在開始時,它將是空的,所以你可以添加第一個單詞。然後,您可以通過給定單詞的列表Binary Search,並在排序列表中插入新單詞(如果未找到),並在找到它時跳過它。

這是一個更適合您軟件的解決方案。

+0

DataTable有任何特殊的功能,如排序? –

+0

@ÖnderÖğretmen我做了一個在Google上快速搜索,沒有找到一個函數二進制搜索實施到數據表。是否有原因顯示希望通過列表進行數據覆蓋? –

+0

爲什麼要使用二分搜索而不是'HashSet '? –

0

Here你可以看到,最快的方法是並行使用LINQ在一起:

 var sampleResults = from DataRow sampleRow in dataTableLocal.AsEnumerable() 
          where sampleRow.Field<string>("FirstColumn") == symbolName 
          select sampleRow; 

     Parallel.ForEach(sampleResults, sampleRow => 
     { 
      string sval = sampleRow["SecondColumn"].ToString(); 
     });