在c#中对250万条内存中的记录进行排序的最佳方法是什么?

时间:2019-03-04 21:52:22

标签: c#

考虑我有课

class Employee
{
    public string Id { get; set; }
    public string Type { get; set; }
    public string Identifier { get; set; }
    public object Resume { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}
List<Employee> employees = LoadEmployees(); //Around 2.5 million to 3 millions employees
employees = employees
                .Where(x => x.Identifier != null)
                .OrderBy(x => x.Identifier)
                .ToArray();

我有一个要求,我希望在内存中加载和排序大约250万名员工,但是Linq查询卡在OrderBy子句中。关于这个有什么建议吗?我创建了Employee类是为了简化我的问题。

1 个答案:

答案 0 :(得分:3)

我将首先使用.Where(x => x.Identifier != null)子句,因为它首先过滤一些数据,然后执行OrderBy。考虑到您只有 个〜250万条记录,并且它们只是诸如stringDateTime之类的基本类型,因此您在此存储中应该没有任何问题情况。

编辑:

我只是将您的代码作为示例运行了,实际上只需几秒钟(例如在我的机器上超过15秒,它没有非常强大的CPU,但仍然不会卡住):

List<Employee> employees = new List<Employee>();
for(int i=0;i<2500000;i++)
{
    employees.Add(new Employee
    {
        Id = Guid.NewGuid().ToString(),
        Identifier = Guid.NewGuid().ToString(),
        Type = i.ToString(),
        StartDate = DateTime.MinValue,
        EndDate = DateTime.Now
    });
}

var newEmployees = employees
    .Where(x => x.Identifier != null)
    .OrderBy(x => x.Identifier)
    .ToArray();

作为第二个编辑,我刚刚进行了一些测试,似乎在某些情况下,使用Parallel Linq的实现可能比串行实现快1.5秒:

var newEmployees1 = employees.AsParallel()
    .Where(x => x.Identifier != null)
    .OrderBy(x => x.Identifier)
    .ToArray();

这些是我得到的最好的数字:

7599 //serial implementation
5752 //parallel linq

但是并行测试可能会在一台计算机上变化,因此我建议您自己进行一些测试,如果仍然发现问题,则可以编辑问题/发布另一台计算机。

使用@Igor在下面的注释中提出的提示,使用StringComparer.OrdinalIgnoreCase的并行实现比简单的并行实现快大约三倍。最终(最快)的代码如下所示:

var employees = employees.AsParallel()
    .Where(x => x.Identifier != null)
    .OrderBy(x => x.Identifier, StringComparer.OrdinalIgnoreCase)
    .ToArray();