如何以最佳方式编写这些linq查询

时间:2015-03-11 01:18:03

标签: c# wpf performance linq optimization

我有一个包含数千个字符串的列表。我想删除包含某些字符串的所有字符串,并选择不同的和最小长度4.目前在查询工作非常好,但我相信性能不是最好的。他们可以写得更有效率吗?

C#5 .net 4.5.2 wpf application

 List<string> lstFoundUrls = new List<string>{"filled with strings"};//lets say 1000

public static List<string> lstBannedUrlExtensions = new List<string> { ".png", ".jpg", ".gif", ".pdf", ".jpeg", ".txt", ".doc", ".docx", ".ppt", ".pptx", ".css", ".js", ".ico" };

lstFoundUrls = lstFoundUrls.Where(pr => lstBannedUrlExtensions.Where(ar => pr.ToLowerInvariant().Contains(ar) == true ).Count<string>() == 0).ToList<string>();

lstFoundUrls = lstFoundUrls.Where(pr => pr != "null").Where(pr => pr.Length > 4).Distinct<string>().ToList<string>();

1 个答案:

答案 0 :(得分:2)

一些事情。

首先,您要计算每个网址包含的禁止扩展数量。因此,如果网址包含.png,则表示您没有停止,并检查该网址是否为.jpg,.gif等。

其次,你在每个字符串上重复执行ToLowerInvariant,而不是每个字符串只执行一次。这意味着您正在对ToLowerInvariant进行X * Y调用,而不仅仅是X。

第三,在执行昂贵的检查后,您将丢弃包含"null"且低于最小长度的所有字符串。应首先进行这些检查 - 尽可能快地丢弃尽可能多的网址。 (“null”检查也是多余的,因为你扔掉了长度为5的任何字符串)。

第四,您使用.Distinct()而非仅使用HashSet开头。

最后,您要遍历每个网址的所有文件扩展名,而不是查找每个网址的文件扩展名并检查O(1)集合(例如Hashset)以查看是否禁止扩展程序。

这样的事情会更好:

        var foundUrls = new HashSet<string>(lstFoundUrls);
        var bannedExtensions = new HashSet<string> { "png", "jpg", "gif", "pdf", "jpeg", "txt", "doc", "docx", "ppt", "pptx", "css", "js", "ico" };

        var filteredUrls = foundUrls.Where(s => s.Length > 4);
        var foundUrlsWithExtension = filteredUrls.ToDictionary(url => url, url => Path.GetExtension(url.ToLowerInvariant()));

        var filteredUrls2 = foundUrlsWithExtension.Where(kvp => !bannedExtensions.Contains(kvp.Value));