2016-08-23 12 views
1

私は300.000以上のレコードを含むデータテーブルを持っています。これは2.000.000以上の単語に相当します。私は各レコードからすべての単語を取得し、うまく動作するアルゴリズムを持っていますが、少し遅いような感じです。C#DataTableフィルター最速の方法

私はこのプログラムをスピードアップしたいと思います。

プログラムはそのように動作します。

  1. データベースからすべてのレコードをdatatableに取得します。
  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

お使いのソフトウェアがあるため、新規追加した単語の指数関数的に遅くなりますし、それらはソートされていないので、それはレコード内のすべての単語のためにそれらのすべてを通過します。

データテーブルをリストにしてリストに挿入するのが基本です。最初は空白になりますので、最初の単語を追加するだけです。次に、指定された単語のリストからBinary Searchを取得し、新しい単語をソートされたリストに挿入します(見つからない場合はスキップします)。

これは、ソフトウェアにとってはるかに最適なソリューションです。

+0

DataTableにはソートされたような特別な機能がありますか? –

+0

@ÖnderÖğretmenGoogleでクイック検索を行い、バイナリ検索の機能がデータに実装されていません表。 Datatable over Listが明示的に必要な理由はありますか? –

+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(); 
     }); 
関連する問題