代码之家  ›  专栏  ›  技术社区  ›  Sergio Tapia

我的代码对于这种简单的LINQ使用效率很低

  •  1
  • Sergio Tapia  · 技术社区  · 14 年前

    我有以下方法,可以解析XML响应中的信息并返回一组用户。

    我选择了创建一个朋友类并返回 List<Friend> 调用方法。

    这是我到目前为止所做的,但我注意到id s.to list().count方法将每个id元素解析为一个列表,然后在for条件中再次执行该操作。这是非常无效的。

    public List<Friend> FindFriends()
    {
        List<Friend> friendList = new List<Friend>();
    
        var friends = doc.Element("ipb").Element("profile").Element("friends").Elements("user");
        var ids = from fr in friends
                  select fr.Element("id").Value;
    
        var names = from fr in friends
                    select fr.Element("name").Value;
    
        var urls = from fr in friends
                    select fr.Element("url").Value;
    
        var photos = from fr in friends
                    select fr.Element("photo").Value;
    
        if (ids.ToList().Count > 0)
        {
            for (int i = 0; i < ids.ToList().Count; i++)
            {
                Friend buddy = new Friend();
                buddy.ID = ids.ToList()[i];
                buddy.Name = names.ToList()[i];
                buddy.URL = urls.ToList()[i];
                buddy.Photo = photos.ToList()[i];
    
                friendList.Add(buddy);
            }
        }            
    
        return friendList;
    }
    
    2 回复  |  直到 6 年前
        1
  •  10
  •   Rex M    14 年前

    第一个问题-是否必须返回 List<Friend> ?你能退一个吗 IEnumerable<Friend> 相反?如果是这样,性能会变得更好:

    IEnumerable<Friend> FindFriends()
    {
        return doc.Descendants("user").Select(user => new Friend {
            ID = user.Element("id").Value,
            Name = user.Element("name").Value,
            Url = user.Element("url").Value,
            Photo = user.Element("photo").Value
        });
    }
    

    这将创建一个 投影 或者一个新对象,它只包含 怎样 创建新的朋友对象而不实际创建它们。当调用者最终开始 foreach 在IEnumerable上。这被称为“延期执行”。

    这也提出了一个假设——所有 <user> XML片段中的节点是朋友。如果不是这样,XML选择的第一部分可能需要是 小的 更复杂。

    正如@anon指出的那样,即使您需要返回 列出<朋友> 由于某些不明显的原因,从你提供的信息来看,你可以打电话给 .ToList() 在返回语句的末尾。这将直接执行我上面描述的投影到一个新的桶中,所以您只创建一个。

        2
  •  0
  •   Rebecca Chernoff    14 年前

    为什么需要单独的id/name/urls/photos变量?把这一切结合起来。如果不需要列表,可以取消tolist()调用。

    List<Friend> friendList = (from f in doc.Element("ipb").Element("profile").Element("friends").Elements("user")
                              select new Friend() { 
                                                     ID = f.Element("id").Value, 
                                                     Name = f.Element("name").Value,
                                                     URL = f.Element("url").Value,
                                                     Photo = f.Element("photo").Value
                                     }).ToList();
    
    return friendList;