列表花费了太多时间

时间:2015-08-22 15:19:28

标签: c# list

我一直在编写一个程序,其中包含100,000个元素的列表,我必须处理具有不同条件的所有元素。这最多花费3秒钟。在此之后,我有一个有效条目列表和我的orignal列表,其中包含100000个元素。新的列表通常有6K - 7K的大小。主要问题是当我使用List.Remove函数或任何其他方法从orignal列表中删除100K元素的无效元素时,它太慢。

请指导我是否应该使用LIST以外的任何其他内容,或者我也可以使用此代码。

我包含了我尝试的所有代码。

for( int k = 0; k < initialList.Count;k++)
{
    combo c = initialList.ElementAt(k);
    if(invalidEntries.Contains(c))
    {
        smartString.Append(c.number1.ToString());
        smartString.Append(c.number2.ToString());
        smartString.Append(c.number3.ToString());
        smartString.Append(c.number4.ToString());
        smartString.Append(c.number5.ToString());
        smartString.Append("   Sum : ");
        smartString.Append(c.sum.ToString());
        smartString.AppendLine();
        InvalidCombo.AppendText(smartString.ToString());
        smartString.Clear();
    }
    else
    {
        smartString.Append(c.number1.ToString());
        smartString.Append(c.number2.ToString());
        smartString.Append(c.number3.ToString());
        smartString.Append(c.number4.ToString());
        smartString.Append(c.number5.ToString());
        smartString.Append("   Sum : ");
        smartString.Append(c.sum.ToString());
        smartString.AppendLine();

        validCombo.AppendText(smartString.ToString());
        smartString.Clear();
    }
}

另外

for(int k=0;k<100000;k++)
{
    combo c = initialList.ElementAt(k);
    if (!invalidEntries.Contains(c))
        validEntries.Add(c);
}

我也尝试过.remove函数,但我认为列表不能接受它。那么任何建议/解决方案?

2 个答案:

答案 0 :(得分:1)

我是struct的粉丝,但是当你和struct像你一样工作时,你必须非常小心。依赖于相等性的List<T>方法(ContainsIndexOfRemove)可能无效,不应使用。 HashSet<T>和类似的相同。
最适合您的情况是将处理与删除相结合。从List<T>删除的最快方法是不使用它的项目删除相关(Remove / RemoveAt)方法! :-)相反,你&#34; compact&#34;列表通过将应保留的项目(及其计数)保留在列表的开头,然后使用RemoveRange方法在列表末尾删除不必要的项目。这是非常有效的,并且避免了在使用&#34; normal&#34;时发生的所有数据块移动。列表删除方法。以下是基于结构定义的示例代码:

public struct combo { public int number1; public int number2; public int number3; public int number4; public int number5; public int sum; public bool invalid; }

void ProcessList(List<combo> list)
{
    int count = 0;
    for (int i = 0; i < list.Count; i++)
    {
        var item = list[i];
        ProcessItem(ref item);
        if (!item.invalid) list[count++] = item;
    }
    list.RemoveRange(count, list.Count - count);
}

void ProcessItem(ref combo item)
{
    // do the processing and set item.invalid=true/false
}

如果你没有改变ProcessItem中的项目,你可以删除ref修饰符,将返回类型更改为bool并使用它来控制项目是否应该是是否从列表中删除。

答案 1 :(得分:0)

以下是使用HashSet的示例。它非常快。

using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var myInts = new HashSet<int>();
            for (var i = 0; i < 100000; i++)
                myInts.Add(i);

            myInts.Remove(62345);
        }
    }
}