我正在编写一个对性能至关重要的程序。我正在查询通常有大约50个条目的原子提要。我需要解析这个可以尽快获得uri链接。
目前我这样做:
var feedUrl = "my path";
using (var feedReader = XmlReader.Create(feedUrl))
{
var feedContent = SyndicationFeed.Load(feedReader);
if (null == feedContent) return null;
foreach (var item in feedContent.Items.Reverse())
{
if (item.Title.Text.Contains("Some text I am looking for"))
{
foreach (var link in item.Links)
{
uri = link.Uri;
}
}
}
}
我从许多来源读到,使用for循环比使用foreach要快得多,所以我试图实现这一点,但继续得到一些错误,说不能将索引应用于SyndicationItem。这似乎是因为SyndicationItem是一个IEnumerable。
所以这给我留下了两个问题: 1.)是否有更好的更有效/更快的方法来做到这一点 2.)我目前正在实施最佳解决方案吗?
答案 0 :(得分:4)
绝大部分时间都可能花在往返接送饲料上。通常,网络延迟时间会使迭代集合所花费的时间相形见绌。
但是,您的feedContent.Items
可能不会立即完全加载到内存中,因此迭代此集合的Reverse
可能会导致比您需要的更多开销。我个人建议使用LINQ语句在一次传递中获取所需的项目,然后调用.ToList()
将结果放入内存中的集合中,该集合在调用.Reverse()
之前很容易逆转。< / p>
var uris =
(from item in feedContent.Items
where item.Title.Text.Contains(searchTerm)
from link in item.Links
select link.Uri)
.ToList()
.Reverse();
或者,如果您只对单个URI感兴趣(您的代码看起来像是在尝试以第一个匹配中的第一个URI结束),那么您也可以调用{{1}并完全跳过.FirstOrDefault()
和Reverse
:
ToList
我玩了一点,并且(我怀疑)这个程序的大约95%的成本(针对Blogger上有25个项目的Feed进行测试)被调用var uris =
(from item in feedContent.Items
where item.Title.Text.Contains(searchTerm)
from link in item.Links
select link.Uri)
.FirstOrDefault()
和{{ 1}}。尝试优化XmlReader.Create()
循环就像用千分尺测量,用蜡笔标记,用斧头切割。
回应你的评论:是的,有办法,也很简单。
SyndicationFeed.Load()
只是重申一下,这不会给你带来任何显着的性能提升,但代码更能表达你真正想做的事情,因此更容易维护。