0

お前らおはよう。

C Sharp .net4、および MS Visual Studio 2010 を使用。

Windows フォーム プログラム用の重複チェッカーを開発しました。それは完全に機能し、数百のレコードがある場合、私のデータグリッドで事実上インスタントです。

私が気付いた問題は、6000 件のレコードが表示されると、まったく効率が悪く、数分かかることです。

既存の設計を改善するか、私が見落とした別の方法をまとめて、この方法をはるかに高速にするための良いヒントを誰かが持っているかどうか、私はさまよっていました。

あなたの助けは再び大歓迎です!

コードは次のとおりです。

public void CheckForDuplicate()
{
    DataGridViewRowCollection coll = ParetoGrid.Rows;
    DataGridViewRowCollection colls = ParetoGrid.Rows;
    IList<String> listParts = new List<String>();
    int count = 0;

    foreach (DataGridViewRow item in coll)
    {
        foreach (DataGridViewRow items in colls)
        {
            count++;
            if ((items.Cells["NewPareto"].Value != null) && (items.Cells["NewPareto"].Value != DBNull.Value))
            {
                if ((items.Cells["NewPareto"].Value != DBNull.Value) && (items.Cells["NewPareto"].Value != null) && (items.Cells["NewPareto"].Value.Equals(item.Cells["NewPareto"].Value)))
                {
                    if ((items.Cells["Part"].Value != DBNull.Value) && (items.Cells["Part"].Value != null) && !(items.Cells["Part"].Value.Equals(item.Cells["Part"].Value)))
                    {
                        listParts.Add(items.Cells["Part"].Value.ToString());

                        dupi = true; //boolean toggle
                    }
                }
            }
        }
    }  
    MyErrorGrid.DataSource = listParts.Select(x => new { Part = x }).ToList();     
}

どんな質問でも私に知らせてください、そして、私はそれらに答えるために最善を尽くします.

4

2 に答える 2

1

これをはるかに効率的にするアプローチがあります。各アイテムのハッシュを計算する必要があります。ハッシュが異なるアイテムは、重複することはできません。

ハッシュを取得したら、ハッシュで並べ替えるか、効率的なキー検索(などDictionary<TKey,TValue>)を備えたデータ構造を使用して、すべての重複を見つけることができます。

于 2012-06-26T08:42:19.743 に答える
1

可能であれば、UIオブジェクトではなく、基になるデータに対してこれを実行する必要があります。ただし、DataRowのセットからシードしているという予感があります。その場合、それを実行できない可能性があります。

ここでの問題の大部分は、名前によるセルの繰り返しの逆参照と、2番目のセルのセットを繰り返し参照しているという事実だと思います。したがって、すべてを前もって行います。

var first = (from row in coll.Cast<DataGridViewRow>()
            let newpareto = row.Cells["NewPareto"].Value ?? DBNull.Value
            let part = row.Cells["Part"].Value ?? DBNull.Value
            where newpareto != DBNull.Value && part != DBNull.Value
            select new 
            { newpareto = newpareto, part = part }).ToArray();

//identical - so a copy-paste job (if not using anonymous type we could refactor)
var second = (from row in colls.Cast<DataGridViewRow>()
            let newpareto = row.Cells["NewPareto"].Value ?? DBNull.Value
            let part = row.Cells["Part"].Value ?? DBNull.Value
            where newpareto != DBNull.Value && part != DBNull.Value
            select new 
            { newpareto = newpareto, part = part }).ToArray();


//now produce our list of strings
var listParts = (from f in first
                where second.Any(v => v.newpareto.Equals(f.newpareto)
                                   && !v.part.Equals(f.part))
                select f.part.ToString()).ToList(); //if you want it as a list.
于 2012-06-26T08:58:03.687 に答える