繁体   English   中英

如何在要从第一个列表中获取第二个列表中不存在的对象的地方加快现有代码的速度?

[英]How can I speed up existing code where I want to get objects from the first list which don't exist on the second list?

我有两种不同的列表( 因为它们在两个不同的数据库中代表两种不同的类型 ):

public partial class PersonOne
{
    public int id { get; set; }
    public string name { get; set; }
    public string surname { get; set; }
    public string address { get; set; }
    public string phone { get; set; }
}

public partial class PersonTwo
{
    public int id { get; set; }
    public string firstname { get; set; }
    public string lastname { get; set; }
    public string email { get; set; }
}

我想消除列表上具有相同的名字和姓氏的重复项,然后从该列表中获取与列表上的对象具有不同的名字和姓氏的对象。 类PartTwo中的名=类PartOne中的名称,类PartTwo =类PartTwo中的姓。

我有该代码,但它非常慢:

List<PersonOne> personOneList = new List<PersonOne>(); // very big list 
List<PersonTwo> personTwoList = new List<PersonTwo>(); // very big list

List<PersonTwo> difference = personTwoList
    .GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
    .Select(x => x.First())
    .Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)))
    .ToList();

尝试这个:

        var HashTable = new Dictionary<Tuple<String,String>,Object>();

        foreach (PersonOne person in personOneList)
        {
            var personTuple = Tuple.Create(person.name, person.surname);
            if (!HashTable.ContainsKey(personTuple))
            {
                HashTable[personTuple] = person;
            }
        }
        foreach (PersonTwo person in personTwoList)
        {
            var personTuple = Tuple.Create(person.firstname, person.lastname);
            if (!HashTable.ContainsKey(personTuple)) {
                HashTable[personTuple] = person;
            }
        }


        var myResult = HashTable.Where(x => x.Value is PersonTwo).Select(x => x.Value).Cast<PersonTwo>().ToList();

HashTable(字典)简化了以下工作:(a)从列表中排除PersonOne类型的人,以及(b)删除第二个人的重复项。

第三,它在O(N)时间而不是O(N^2)

首先,我建议您对Person使用单个类。 如果存在差异,则将父类作为Person并从Person继承PersonOne和PersonTwo。

对于您现有的设计,我建议您使用IEnumerable而不是List。 看看

Stopwatch sw = new Stopwatch();
sw.Start();

List<PersonTwo> difference = personTwoList
.GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
.Select(x => x.First())
.Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)))    
.ToList();

        sw.Stop();

        Console.WriteLine("Time elapsed: {0}", sw.ElapsedTicks);//took 83333ms

        Stopwatch sw1 = new Stopwatch();
        sw1.Start();

        IEnumerable<PersonTwo> difference1 = personTwoList
            .GroupBy(x => new { FirstName = x.firstname.ToLower(), LastName = x.lastname.ToLower() })
            .Select(x => x.First())
            .Where(x => !personOneList.Any(y => y.name.Equals(x.firstname, StringComparison.InvariantCultureIgnoreCase) && y.surname.Equals(x.lastname, StringComparison.InvariantCultureIgnoreCase)));

        sw1.Stop();

        Console.WriteLine("Time elapsed: {0}", sw1.ElapsedTicks);//took 9ms
        Console.ReadLine();

结果基于以下生成的测试数据

for (int i = 0; i < 500; i++)
        {
            personOneList.Add(new PersonOne
                {
                    surname = "a" + i,
                    name = "b"+ i
                });

            personTwoList.Add(new PersonTwo
            {
                lastname = "a" + i,
                firstname = "b" + i
            });
        }

        for (int i = 0; i < 100; i++)
        {
            personTwoList.Add(new PersonTwo
            {
                lastname = "c" + i,
                firstname = "d" + i
            });
        }

        for (int i = 0; i < 100; i++)
        {
            personTwoList.Add(new PersonTwo
            {
                lastname = "a" + i,
                firstname = "b" + i
            });
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM