优化文本转换为整数列表

时间:2013-01-13 09:00:20

标签: c# string .net-4.0

我正在编写一个接受用户输入的UI应用程序 -

他粘贴到Textbox的最多50,000个条目,我需要将其转换为List<Uint32>(区别)

在此过程中,我在'文本框'中显示Distict列表(输出)。

我正在拆分文本并将其转换为不同的Uint32列表 然后我将列表转换为数组。

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);

速度较慢(比使用StringBuilder慢约25%)

我觉得我的功能设计错了,两次转换。

是否有提高此功能的性能?

修改 我的错, 缓慢的部分是ListOfHeliostatsText.Text = builder.ToString();

我会继续阅读答案。

3 个答案:

答案 0 :(得分:1)

您测量不正确。缓慢的部分是

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

缓慢的部分是:

SomeTextBox.Text = builder.ToString();

问题是你在文本框中输入了一条巨大的线条。如果你把每个字符串放在自己的行....

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

...你会观察到大约50倍的加速。

答案 1 :(得分: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

答案 2 :(得分: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();
}

并且接受我的建议,不要让该方法做更多的事情而不仅仅是生成该列表。您可以在该功能之外填写该文本框,它不属于那里。