我怎样才能加快这个linq查询?
这需要很长时间,当我在列表中放置大量对象时,会出现内存异常。
List<DirectoryInfo> directoriesThatWillBeCreated = new List<DirectoryInfo>();
// some code to fill the list
// ..
// ..
List<FileInfo> FilesThatWillBeCopied = new List<FileInfo>();
// some code to fill the list
//....
directoriesThatWillBeCreated = (from a in FilesThatWillBeCopied
from b in directoriesThatWillBeCreated
where a.FullName.Contains(b.FullName)
select b).ToList();
我希望我可以做previous solution 之类的事情,但在处理不同类型的对象时我不知道该怎么做。我是否必须创建一个新类,然后将所有FileInfo和DirectoryInfo对象转换为该类,然后执行查询?此外,FileInfo和DirectoryInfo类是密封的,我不能从它们继承,因此我将不得不创建一个新类,这将是无效的。至少这将比该查询更有效,因为该查询需要永远。
答案 0 :(得分:0)
这很慢,因为代码在目录列表中为每个文件进行线性搜索。试试这个:
var dirlist = FilesThatWillBeCopied
.Select(f => Directory.GetParent(f.FullName))
.GroupBy(d => d.FullName)
您可能需要稍微使用语法,但希望您明白这一点。
答案 1 :(得分:0)
您可以做的一件事是将Contains更改为StartsWith。如果匹配失败,StartsWith
将更快失败。
directoriesThatWillBeCreated = (from a in FilesThatWillBeCopied
from b in directoriesThatWillBeCreated
where a.FullName.StartsWith(b.FullName)
select b).ToList();
但这不是一个完整的解决方案。如果FilesThatWillBeCopied
包含M个项且directoriesThatWillBeCreated
包含N个元素,那么您的查询将处理MxN字符串比较。
要尝试的另一个优化,首先遍历directoriesThatWillBeCreated
,然后选择与FileInfo
中的任何FilesThatWillBeCopied
匹配的优化。通过检查是否有任何匹配,您可以在找到匹配项后暂停测试文件。这可以这样做:(警告,记事本代码如下)
directoriesThatWillBeCreated = directoryThatWillBeCreated
.Select(b => FilesThatWillBeCopied
.Any(a => a.FullName.StartsWith(b.FullName)));
答案 2 :(得分:0)
我建议使用HashSet<DirectoryInfo>
进行比较,但不幸的是,DirectoryInfo
没有实现适当的相等比较,因此字符串必须这样做。 (另一个选择是实现自己的IComparer<DirectoryInfo>
。)此外,您应该在名称上使用StringComparer.InvariantCultureIgnoreCase
,除非您确定两个集合具有相同的大小写。
var dirs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// fill dirs
var files = new List<FileInfo>();
// fill files
var result = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
foreach (var file in files)
{
var dir = file.Directory;
while (dir != null && !result.Contains(dir.FullName))
{
if (dirs.Contains(dir.FullName))
result.Add(dir.FullName);
dir = dir.Parent;
}
}
这个解决方案根本不使用LINQ,但是当你追求性能并且最直接的LINQ解决方案太慢时,通常会出现这种情况。