Enumerable.Take
действительно поток результатов;он не буферизирует свой источник целиком, а затем возвращает только первое N. Хотя, глядя на ваше исходное решение, проблема в том, что ввод, где вы хотите сделать Take
, равен String.Split
.К сожалению, этот метод не использует какого-либо отложенного выполнения;он охотно создает массив всех «разбиений» и затем возвращает его.
Следовательно, методика получения потоковой последовательности слов из некоторого текста будет выглядеть примерно так:
var words = src.StreamingSplit() // you'll have to implement that
.Take(1000);
Однако я отмечу, что остальная часть вашего запроса:
...
.GroupBy(str => str) // group words by the value
.Select(g => new
{
str = g.Key, // the value
count = g.Count() // the count of that value
});
Обратите внимание, что GroupBy
- это операция буферизации - вы можете ожидать, что все 1000 слов из ее источника будут храниться где-то в процессе передачи групп.
Как я понимаю, варианты:
- Если вы не возражаете, просматривая весь текст для разбиения целей, тогда
src.Split().Take(1000)
подойдет.Недостатком является потраченное впустую время (чтобы продолжить расщепление после того, как оно больше не нужно) и пустое пространство (для хранения всех слов в массиве, даже если только первая тысяча) потребуется.Однако rest запроса не будет обрабатывать больше слов, чем необходимо. - Если вы не можете позволить себе сделать (1) из-за нехватки времени / памяти, используйте
src.StreamingSplit().Take(1000)
или эквивалентный.В этом случае исходный текст не будет обработан после того, как будет найдено 1000 слов.
Обратите внимание, что эти 1000 слов сами в конечном итоге будут буферизованы предложением GroupBy
в обоих случаях.