0

ユーザーからの入力を受け入れる UI アプリケーションを作成しています -

彼がに貼り付けた最大50,000のエントリTextbox、私が変換する必要があるList<Uint32>(個別)

その過程で、「テキストボックス」に地区リスト (出力) を表示します。

テキストを分割し、それを Uint32 の Distinct リストに変換しています。次に、リストを配列に変換します。

private List<UInt32> ConvertTextToList(string TextBoxText)
{
string[] TextBoxSplitted = TextBoxText.Split(new string[] { Environment.NewLine},StringSplitOptions.RemoveEmptyEntries); //Fast
            var TextBoxSplittedAsList = TextBoxSplitted.ToList<string>(); //Fast
            List<UInt32> lp = TextBoxSplittedAsList.ConvertAll(new Converter<string, UInt32>(element => Convert.ToUInt32(element))); //Fast
            List<UInt32> uintList = lp.Distinct<UInt32>().ToList<UInt32>(); //Fast
            UInt32[] uintListArray = uintList.ToArray(); //Fast

            //Slow part (measured 15 sec on core2duo 2.53GHz)
            StringBuilder builder = new StringBuilder();
            Array.ForEach(uintListArray, x => builder.Append(x));                
            //Done slow part

            SomeTextBox.text = builder.ToString();

            return uintList;
}

最初に試したのは-ListOfHeliostatsText.Text = string.Join(",", uintListArray);

どちらが遅かったか ( を使用するよりも約 25% 遅かったStringBuilder)

私の関数は間違って設計されていると感じています.2つの多くの変換です。

この関数のパフォーマンスを改善する方法はありますか?

編集: 私の悪い、遅い部分は ListOfHeliostatsText.Text = builder.ToString(); です。

私は答えを読み続けます。

4

3 に答える 3

1

あなたは間違って測定しました。遅い部分はそうではありません

StringBuilder builder = new StringBuilder();
Array.ForEach(uintListArray, x => builder.Append(x)); 

遅い部分は次のとおりです。

SomeTextBox.Text = builder.ToString();

問題は、テキスト ボックスに 1 つの巨大な行を入力していることです。各文字列を独自の行に入れると....

Array.ForEach(uintListArray, x => builder.AppendLine(x.ToString()));

...およそ 50 倍の高速化が見られます。

于 2013-01-13T09:58:14.380 に答える
0

潜在的に多くのエントリがあるため、文字列分割操作を使用して中間値を中間配列に取得しても役に立たないと思います。それは多くのオーバーヘッドです。速度と効率が目標である場合は、読み取られるアイテムを生成する文字列を効果的に読み取ってトークン化する必要があります。このように、これらすべての値を保持する中間配列は必要ありません。

すべての個別の値を取得したい場合は、すべてを に投げることができますHashSet<T>。ただし、ここで示す例では、いくつかの LINQ とDistinct()メソッド (独自のオーバーヘッドがあります) を使用します。

// a naive tokenizing iterator
IEnumerable<string> Tokenize(string str, string separator)
{
    var current = 0;
    while (current < str.Length)
    {
        // we're effectively scanning through the string
        var next = str.IndexOf(separator, current);
        if (next == -1)
        {
            next = str.Length;
        }
        var token = str.Substring(current, next - current);
        yield return token;
        current = next + 1;
    }
}

List<uint> ConvertTextToList(string text)
{
    return Tokenize(text, ",")
        .Select(token => Convert.ToUInt32(token))
        .Distinct()
        .ToList();
}

そして、私のアドバイスに従ってください。そのメソッドに、そのリストを生成する以上のことをさせないでください。その関数の外でそのテキストボックスに入力できますが、そこには属していません。

于 2013-01-13T09:28:14.990 に答える
0

これを試してみてください:

private List<UInt32> ConvertTextToList(string TextBoxText)
{
   ....
    var TextBoxSplittedAsList = TextBoxSplitted.ToList<string>(); //Fast

    TextBoxSplittedAsList.Select(int.Parse).ToList();
    TextBoxSplittedAsList.Distinct().ToList(); // to get the distinct values
于 2013-01-13T09:05:57.910 に答える