2014-11-10 2 views
3

Я пытаюсь оптимизировать процедуру, которая выглядит вроде как это (упрощенный):Проверьте обратный выход содержит элементы

public async Task<IEnumerable<Bar>> GetBars(ObjectId id){ 
    var output = new Collection<Bar>(); 

    var page = 1; 
    var hasMore = true; 

    while(hasMore) { 
     var foos = await client.GetFoos(id, page); 

     foreach(var foo : foos) { 

      if(!Proceed(foo)) { 
       hasMore = false; 
       break; 
      } 

      output.Add(new Bar().Map(foo) 
     } 

     page++; 

    return output; 
} 

Метод, который называет GetBars() выглядит как этот

public async Task<Baz> GetBaz(ObjectId id){ 
    var bars = await qux.GetBars(); 

    if(bars.Any() { 
     var bazBaseData = qux.GetBazBaseData(id); 
     var bazAdditionalData = qux.GetBazAdditionalData(id); 

     return new Baz().Map(await bazBaseData, await bazAdditionalData, bars); 
    } 
} 

GetBaz() возвращает от 0 до множества предметов. Поскольку мы запускаем несколько миллионов идентификаторов, мы сначала добавили оператор if(bars.Any()) в качестве начальной попытки ускорить приложение.

Поскольку ожидается GetBars(), он блокирует нить до тех пор, пока не соберет все свои данные (что может занять некоторое время). Моя идея состояла в том, чтобы использовать возврат доходности, а затем заменить if(bars.Any()) проверкой, проверяющей, получится ли хотя бы один элемент, поэтому мы можем отпустить два других асинхронных метода за это время (что также требует времени для выполнения).

Вопрос в том, как это сделать. Я знаю, System.Linq.Count() и System.Linq.Any() побеждает всю идею возврата доходности, и если я проверю первый элемент в перечислимом, он будет удален из перечислимого.

Есть ли другой вариант/лучший вариант помимо добавления, например, параметра out к GetBars()?

TL; DR: Как проверить, содержит ли перечислимый из доходности доход какие-либо объекты, не начиная его повторять?

+0

Исправьте мой, если у меня получилось неправильное впечатление - вы пытаетесь найти способ узнать, содержит ли 'GetBars()' элементы, проверяющие первый элемент. Правильно? –

+0

@ Это верно. Я добавлю это к исходному вопросу. – Asser

+0

Является ли 'wait клиент.GetFoos' самой длинной частью вашего метода' GetBars'? – Rawling

ответ

4

Для вашего фактического вопроса «Как проверить, содержит ли перечислимое из возврата доход какие-либо объекты, не начиная повторять его?» ну, ты этого не делаешь.

Это просто, вы не можете использовать период, так как единственное, что вы можете сделать с IEnumerable, это хорошо, чтобы его перечислить. Вызов Any() не является проблемой, так как это «делает» только перечисляет первый элемент (а не весь список), но невозможно перечислить ничего, поскольку многие ienumerables не существуют ни в какой форме, кроме как (не может быть никакой поддержки, невозможно проверить, нет ли чего-то, что еще не существует, по дизайну это не имеет смысла)

Редактировать: также я не вижу никакой доходности в вашем код, вы смешиваете ожидаемые и понятные понятия (совершенно не связанные)?

+0

Хорошо. Это довольно прямо. Спасибо. Редактировать: так выглядит код перед оптимизацией. – Asser

Смежные вопросы