通过使用产量或改变算法来优化代码

发布于 2024-08-16 07:31:55 字数 983 浏览 7 评论 0原文

下面的代码可以工作,但我想使用产量或通过更改算法来优化代码。

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    var bookAndAuthorList = new List<Book>();
    List<Author> AuthorNameList = getAuthorName(keyword);
    foreach (var author in AuthorNameList)
    {
        XmlNode booksNames = getBook(author);
        XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

        var bookNameList = (
            from x1 in XDOCbooksNames.Descendants("Books")
            select x1.Elements("book").Select(g => g.Attribute("name").Value))
            .ToList();
        foreach (var bookName in bookNameList)
        {
            bookAndAuthorList.Add(new Book()
            {
                authorName = author.authorName,
                bookName = bookName
            });
        }
    }
    return bookAndAuthorList;
}

public class Book
{
    public string authorName { get; set; }
    public string bookName { get; set; }
}

The code below works but I want to optimize the code using yield or by changing algorithm.

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    var bookAndAuthorList = new List<Book>();
    List<Author> AuthorNameList = getAuthorName(keyword);
    foreach (var author in AuthorNameList)
    {
        XmlNode booksNames = getBook(author);
        XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

        var bookNameList = (
            from x1 in XDOCbooksNames.Descendants("Books")
            select x1.Elements("book").Select(g => g.Attribute("name").Value))
            .ToList();
        foreach (var bookName in bookNameList)
        {
            bookAndAuthorList.Add(new Book()
            {
                authorName = author.authorName,
                bookName = bookName
            });
        }
    }
    return bookAndAuthorList;
}

public class Book
{
    public string authorName { get; set; }
    public string bookName { get; set; }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乖乖 2024-08-23 07:31:55

鲁本斯和卢克的回应正确解释了产量的使用。

然而,这对我来说看起来很可疑。

XmlNode booksNames = getBook(author);
XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

您将 XML 转换为字符串,然后再次解析它,只是因为您想将其从 DOM 节点转换为 Xml.Linq 节点。如果你谈论的是优化,那么这比创建额外的列表效率低得多。

Responses by Rubens and Luke correctly explain the use of yield.

However, this looks suspicious to me.

XmlNode booksNames = getBook(author);
XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

You convert XML to string and then parse it again, only because you want to convert it from DOM Node to Xml.Linq node. If you are talking about optimization, then this is much more inefficient than creating an extra list.

不必在意 2024-08-23 07:31:55

为了快速获胜,您可以删除 .ToList() 调用。您所做的只是枚举项目,因此无需这样做。同样,无需创建 bookAndAutherList。

最终我认为你可以将其简化为:

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    return from author in getAuthorName(keyword)
           let book = getBook(author)
           from xmlBook in XDocument.Parse(book.OuterXml).Descendants("Books")
           select new Book
           {
               authorName = author.AuthorName,
               bookName = xmlBook.Attribute("name").Value
           };
}

As a quick win, you can remove the .ToList() call. All you're doing is enumerate items, so there's no need to do that. Similarly, there's no need to create bookAndAutherList.

Eventually I think you can strip it down to this:

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    return from author in getAuthorName(keyword)
           let book = getBook(author)
           from xmlBook in XDocument.Parse(book.OuterXml).Descendants("Books")
           select new Book
           {
               authorName = author.AuthorName,
               bookName = xmlBook.Attribute("name").Value
           };
}
余生一个溪 2024-08-23 07:31:55

不确定你会得到很多“优化”。当您经常在使用正在生成的枚举时中断部分时,最好使用yield,这样您就不会进行不必要的计算。但这里有一句话:

这是未经测试的。

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    foreach (var author in getAuthorName(keyword))
    {
        XDocument XDOCbooksNames = XDocument.Parse(getBook(author).OuterXml);

        var bookNameList = from x1 in XDOCbooksNames.Descendants("Books")
                            select x1.Elements("book").Select(g => g.Attribute("name").Value);

        foreach (var bookName in bookNameList)
        {
            yield return new Book()
                {
                    authorName = author.authorName,
                    bookName = bookName
                };
        }
    }
}

我做了什么:

  1. 删除 ToList()
    表达式,它已经返回一个
    可数。删除了一些代码
    将 getAuthorName 合并到
    foreach(注意 - 如果可以的话,请确保该函数也能产生并且可枚举)
  2. 产生返回而不是添加到列表中

Not sure you'll get much 'optimization'. Yield is better used when you would often break part way through using the enumeration you are generating, so that you don't do unnecessary computation. But here goes:

This is untested.

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    foreach (var author in getAuthorName(keyword))
    {
        XDocument XDOCbooksNames = XDocument.Parse(getBook(author).OuterXml);

        var bookNameList = from x1 in XDOCbooksNames.Descendants("Books")
                            select x1.Elements("book").Select(g => g.Attribute("name").Value);

        foreach (var bookName in bookNameList)
        {
            yield return new Book()
                {
                    authorName = author.authorName,
                    bookName = bookName
                };
        }
    }
}

What I did:

  1. Remove the ToList() on the
    expression, it already returns an
    enumerable. removed some code by
    consolidating getAuthorName into the
    foreach (note - make sure that function yields and ienumerable too, if you can)
  2. Yield return instead of adding to a list
青衫儰鉨ミ守葔 2024-08-23 07:31:55

试试这个:

foreach (var bookName in bookNameList)
{
    yield return new Book()
    {
        authorName = author.authorName,
        bookName = bookName
    };
}

并删除其他 return 语句。

Try this:

foreach (var bookName in bookNameList)
{
    yield return new Book()
    {
        authorName = author.authorName,
        bookName = bookName
    };
}

And remove other return statement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文