2009-12-29 1 views
1

Приведенный ниже код работает, но я хочу оптимизировать код с использованием доходности или путем изменения алгоритма.Оптимизация кода с помощью алгоритма доходности или изменения

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; } 
} 
+0

Использование 'yield' не даст вам реальной выгоды, так как вы все равно будете создавать новый объект' Book' на каждой итерации. –

+1

@Aviad, который может помочь, если существует условие выхода в цикле, в котором используются экземпляры книг –

+2

Оптимизируйте для чего? И почему? – LukeH

ответ

6

Как быстро победить, может удалить вызов .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 
      }; 
} 
+1

Это лучший ответ. +1. @NETQuestion: LINQ автоматически создает IEnumerable запросы, которые реализуют ленивую итерацию (т. Е. Используют ключевое слово yield во время итерации). Пока вы сохраняете свой источник данных в памяти, и ваш код, безусловно, подразумевает, что вы это делаете, просто верните запрос LINQ, и вы стали золотым. – Randolpho

+2

Кроме того, я хотел упомянуть, что пусть на удивление недоиспользуется. Еще +1 к случайному ответу, просто для его упоминания! :) – Randolpho

+1

+1 для «let» - Я просто подумал: «Подождите, это F # или еще что-то?» LINQ - это действительно язык. –

0

Попробуйте это:

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

и удалить другие return заявление.

1

Не уверен, что вы получите большую «оптимизацию». Доходность лучше использовать, когда вы часто ломаете часть пути, используя нумерацию, которую вы генерируете, чтобы вы не делали ненужных вычислений. Но здесь идет:

Это непроверено.

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 в Еогеасп (примечание - убедитесь, что функция дает и IEnumerable тоже, если вы можете)
  2. Выход возврата вместо добавления в список
9

Ответы Рубенса и Луки правильно объяснить использование урожая.

Однако это выглядит подозрительно для меня.

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

Вы преобразовать XML в строку, а затем разобрать его снова, только потому, что вы хотите, чтобы преобразовать его из DOM узла к узлу Xml.Linq. Если вы говорите об оптимизации, то это гораздо более неэффективно, чем создание дополнительного списка.

+1

Хорошо, если бы у меня было больше очков, я бы добавил +1! –

+2

Похоже, лучшим решением для этого является реализация getBook, который возвращает «XElement» или «XDocument» –

+0

+1, приятный улов! –