如果有可能加速 From-Where-Select 方法?

If it possible accelerate From-Where-Select method?

我有两个代码:

第一个:

struct pair_fiodat {string fio; string dat;}
List<pair_fiodat> list_fiodat = new List<pair_fiodat>();
// list filled 200.000 records, omitted.
foreach(string fname in XML_files)
{
// get FullName and Birthday from file. Omitted.
var usersLookUp = list_fiodat.ToLookup(u => u.fio, u => u.dat); // create map
    var dates = usersLookUp[FullName];
    if (dates.Count() > 0)
    {
        foreach (var dt in dates)
        {
            if (dt == BirthDate) return true;
        }
    }
}

第二个:

struct pair_fiodat {string fio; string dat;}
List<pair_fiodat> list_fiodat = new List<pair_fiodat>();
// list filled 200.000 records, omitted.
foreach(string fname in XML_files)
{
// get FullName and Birthday from file. Omitted.
    var members = from s in list_fiodat where s.fio == FullName & s.dat == Birthdate select s;
    if (members.Count() > 0 return true;
}

他们做同样的工作 - 按姓名和生日搜索用户。 第一个工作非常快。 第二个非常慢(10x-50x) 请告诉我是否可以加速第二个? 我的意思是可能需要特殊准备的清单? 我尝试排序:list_fiodat_sorted = list_fiodat.OrderBy(x => x.fio).ToList();,但是...

我跳过你的第一个测试并将 Count() 更改为 Any()(count 迭代所有列表,而 any 在有元素时停止)

public bool Test1(List<pair_fiodat> list_fiodat)
{
    foreach (string fname in XML_files)
    {
        var members = from s in list_fiodat 
            where s.fio == fname & s.dat == BirthDate
            select s;
        if (members.Any())
            return true;
    }

    return false;
}

如果你想优化某些东西,你必须留下能为你提供语言的舒适的东西,因为通常这些东西不是免费的,它们是有成本的。 例如,for 比 foreach 快。比较难看,需要两句获取变量,但是速度更快。如果你迭代一个非常大的集合,每次迭代总和。 LINQ 非常强大,使用它非常棒,但需要付出代价。如果你把它换成另一个“for”,你就节省了时间。

public bool Test2(List<pair_fiodat> list_fiodat)
{
    for (int i = 0; i < XML_files.Count; i++)
    {
        string fname = XML_files[i];
        for (int j = 0; j < list_fiodat.Count; j++)
        {
            var s = list_fiodat[j];

            if (s.fio == fname & s.dat == BirthDate)
            {
                return true;
            }
        }
    }

    return false;
}

对于普通集合没有区别,通常你使用 foeach、LINQ...但在极端情况下,你必须使用低级别。

在您的第一个测试中,ToLookup 是关键。这需要很长时间。想一想:您正在迭代所有列表,创建并填充地图。这在任何情况下都是不好的,但考虑一下您要查找的项目位于列表开头的情况:您只需要几次迭代即可找到它,但您花时间在列表的每个项目上创建地图.只有在最坏的情况下,由于创建本身,时间与地图创建相似并且总是更糟。

如果您需要地图很有趣,例如,所有符合某些条件的项目,获取列表而不是找到单个项目。您花时间创建地图一次,但多次使用地图,每次都节省时间(地图是“直接访问”,而 for 是“顺序访问”)。