循环原子进料的最快方法

时间:2012-02-02 02:42:17

标签: c# for-loop rss atom-feed

我正在编写一个对性能至关重要的程序。我正在查询通常有大约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.)我目前正在实施最佳解决方案吗?

1 个答案:

答案 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()循环就像用千分尺测量,用蜡笔标记,用斧头切割。

更新2

回应你的评论:是的,有办法,也很简单。

SyndicationFeed.Load()

只是重申一下,这不会给你带来任何显着的性能提升,但代码更能表达你真正想做的事情,因此更容易维护。