Program.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. #nullable disable
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.Labs.Linq;
  10. using System.Threading.Tasks;
  11. namespace FasterLinq
  12. {
  13. class Program
  14. {
  15. static void Main(string[] args)
  16. {
  17. var N = 4;
  18. Sync(N);
  19. Async1(N).Wait();
  20. Async2(N).Wait();
  21. }
  22. static void Sync(int n)
  23. {
  24. Console.WriteLine("IEnumerable<T> and IFastEnumerable<T>");
  25. Console.WriteLine();
  26. var sw = new Stopwatch();
  27. var N = 10_000_000;
  28. var next = new Action<int>(_ => { });
  29. var slowRange = Enumerable.Range(0, N);
  30. var fastRange = FastEnumerable.Range(0, N);
  31. var brdgRange = slowRange.ToFastEnumerable();
  32. var slow = slowRange.Where(x => x % 2 == 0).Select(x => x + 1);
  33. var fast = fastRange.Where(x => x % 2 == 0).Select(x => x + 1);
  34. var brdg = brdgRange.Where(x => x % 2 == 0).Select(x => x + 1).ToEnumerable();
  35. Console.WriteLine("slow.Sum() = " + slow.Aggregate(0, (sum, x) => sum + x));
  36. Console.WriteLine("fast.Sum() = " + fast.Aggregate(0, (sum, x) => sum + x));
  37. Console.WriteLine("brdg.Sum() = " + brdg.Aggregate(0, (sum, x) => sum + x));
  38. Console.WriteLine();
  39. for (var i = 0; i < n; i++)
  40. {
  41. sw.Restart();
  42. {
  43. slow.ForEach(next);
  44. }
  45. Console.WriteLine("SLOW " + sw.Elapsed);
  46. sw.Restart();
  47. {
  48. fast.ForEach(next);
  49. }
  50. Console.WriteLine("FAST " + sw.Elapsed);
  51. sw.Restart();
  52. {
  53. brdg.ForEach(next);
  54. }
  55. Console.WriteLine("BRDG " + sw.Elapsed);
  56. Console.WriteLine();
  57. }
  58. Console.WriteLine();
  59. }
  60. static async Task Async1(int n)
  61. {
  62. Console.WriteLine("IAsyncEnumerable<T> and IAsyncFastEnumerable<T> - Synchronous query operators");
  63. Console.WriteLine();
  64. var sw = new Stopwatch();
  65. var N = 10_000_000;
  66. var next = new Func<int, Task>(_ => Task.CompletedTask);
  67. var slowRange = AsyncEnumerable.Range(0, N);
  68. var fastRange = AsyncFastEnumerable.Range(0, N);
  69. var brdgRange = slowRange.ToAsyncFastEnumerable();
  70. var slow = slowRange.Where(x => x % 2 == 0).Select(x => x + 1);
  71. var fast = fastRange.Where(x => x % 2 == 0).Select(x => x + 1);
  72. var brdg = brdgRange.Where(x => x % 2 == 0).Select(x => x + 1).ToAsyncEnumerable();
  73. Console.WriteLine("slow.Sum() = " + slow.Aggregate(0, (sum, x) => sum + x).Result);
  74. Console.WriteLine("fast.Sum() = " + fast.Aggregate(0, (sum, x) => sum + x).Result);
  75. Console.WriteLine("brdg.Sum() = " + brdg.Aggregate(0, (sum, x) => sum + x).Result);
  76. Console.WriteLine();
  77. for (var i = 0; i < n; i++)
  78. {
  79. sw.Restart();
  80. {
  81. await slow.ForEachAsync(next);
  82. }
  83. Console.WriteLine("SLOW " + sw.Elapsed);
  84. sw.Restart();
  85. {
  86. await fast.ForEachAsync(next);
  87. }
  88. Console.WriteLine("FAST " + sw.Elapsed);
  89. sw.Restart();
  90. {
  91. await brdg.ForEachAsync(next);
  92. }
  93. Console.WriteLine("BRDG " + sw.Elapsed);
  94. Console.WriteLine();
  95. }
  96. Console.WriteLine();
  97. }
  98. static async Task Async2(int n)
  99. {
  100. Console.WriteLine("IAsyncEnumerable<T> and IAsyncFastEnumerable<T> - Asynchronous query operators");
  101. Console.WriteLine();
  102. var sw = new Stopwatch();
  103. var N = 10_000_000;
  104. var next = new Func<int, Task>(_ => Task.CompletedTask);
  105. var slowRange = AsyncEnumerable.Range(0, N);
  106. var fastRange = AsyncFastEnumerable.Range(0, N);
  107. var brdgRange = slowRange.ToAsyncFastEnumerable();
  108. var slow = slowRange.Where(x => Task.FromResult(x % 2 == 0)).Select(x => Task.FromResult(x + 1));
  109. var fast = fastRange.Where(x => Task.FromResult(x % 2 == 0)).Select(x => Task.FromResult(x + 1));
  110. var brdg = brdgRange.Where(x => Task.FromResult(x % 2 == 0)).Select(x => Task.FromResult(x + 1)).ToAsyncEnumerable();
  111. Console.WriteLine("slow.Sum() = " + slow.Aggregate(0, (sum, x) => sum + x).Result);
  112. Console.WriteLine("fast.Sum() = " + fast.Aggregate(0, (sum, x) => sum + x).Result);
  113. Console.WriteLine("brdg.Sum() = " + brdg.Aggregate(0, (sum, x) => sum + x).Result);
  114. Console.WriteLine();
  115. for (var i = 0; i < n; i++)
  116. {
  117. sw.Restart();
  118. {
  119. await slow.ForEachAsync(next);
  120. }
  121. Console.WriteLine("SLOW " + sw.Elapsed);
  122. sw.Restart();
  123. {
  124. await fast.ForEachAsync(next);
  125. }
  126. Console.WriteLine("FAST " + sw.Elapsed);
  127. sw.Restart();
  128. {
  129. await brdg.ForEachAsync(next);
  130. }
  131. Console.WriteLine("BRDG " + sw.Elapsed);
  132. Console.WriteLine();
  133. }
  134. Console.WriteLine();
  135. }
  136. }
  137. }
  138. namespace System
  139. {
  140. public interface IAsyncDisposable
  141. {
  142. Task DisposeAsync();
  143. }
  144. }
  145. namespace System.Collections.Generic
  146. {
  147. public interface IAsyncEnumerable<out T>
  148. {
  149. IAsyncEnumerator<T> GetAsyncEnumerator();
  150. }
  151. public interface IAsyncEnumerator<out T> : IAsyncDisposable
  152. {
  153. Task<bool> MoveNextAsync();
  154. T Current { get; }
  155. }
  156. public interface IFastEnumerable<out T>
  157. {
  158. IFastEnumerator<T> GetEnumerator();
  159. }
  160. public interface IFastEnumerator<out T> : IDisposable
  161. {
  162. T TryGetNext(out bool success);
  163. }
  164. public interface IAsyncFastEnumerable<out T>
  165. {
  166. IAsyncFastEnumerator<T> GetAsyncEnumerator();
  167. }
  168. public interface IAsyncFastEnumerator<out T> : IAsyncDisposable
  169. {
  170. Task<bool> WaitForNextAsync();
  171. T TryGetNext(out bool success);
  172. }
  173. }
  174. namespace System.Labs.Linq
  175. {
  176. internal abstract class Iterator<T> : IEnumerable<T>, IEnumerator<T>
  177. {
  178. private readonly int _threadId;
  179. internal int _state;
  180. protected T _current;
  181. protected Iterator()
  182. {
  183. _threadId = Environment.CurrentManagedThreadId;
  184. }
  185. public abstract Iterator<T> Clone();
  186. public virtual void Dispose()
  187. {
  188. _state = -1;
  189. }
  190. public IEnumerator<T> GetEnumerator()
  191. {
  192. Iterator<T> enumerator = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : Clone();
  193. enumerator._state = 1;
  194. return enumerator;
  195. }
  196. public abstract bool MoveNext();
  197. public T Current => _current;
  198. object IEnumerator.Current => _current;
  199. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  200. public void Reset() => throw new NotSupportedException();
  201. }
  202. internal abstract class AsyncIterator<T> : IAsyncEnumerable<T>, IAsyncEnumerator<T>
  203. {
  204. private readonly int _threadId;
  205. internal int _state;
  206. protected T _current;
  207. protected AsyncIterator()
  208. {
  209. _threadId = Environment.CurrentManagedThreadId;
  210. }
  211. public abstract AsyncIterator<T> Clone();
  212. public virtual Task DisposeAsync()
  213. {
  214. _state = -1;
  215. return Task.CompletedTask;
  216. }
  217. public IAsyncEnumerator<T> GetAsyncEnumerator()
  218. {
  219. AsyncIterator<T> enumerator = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : Clone();
  220. enumerator._state = 1;
  221. return enumerator;
  222. }
  223. public abstract Task<bool> MoveNextAsync();
  224. public T Current => _current;
  225. }
  226. internal abstract class FastIterator<T> : IFastEnumerable<T>, IFastEnumerator<T>
  227. {
  228. private readonly int _threadId;
  229. internal int _state;
  230. protected FastIterator()
  231. {
  232. _threadId = Environment.CurrentManagedThreadId;
  233. }
  234. public abstract FastIterator<T> Clone();
  235. public virtual void Dispose()
  236. {
  237. _state = -1;
  238. }
  239. public IFastEnumerator<T> GetEnumerator()
  240. {
  241. FastIterator<T> enumerator = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : Clone();
  242. enumerator._state = 1;
  243. return enumerator;
  244. }
  245. public abstract T TryGetNext(out bool success);
  246. }
  247. internal abstract class AsyncFastIterator<T> : IAsyncFastEnumerable<T>, IAsyncFastEnumerator<T>
  248. {
  249. private readonly int _threadId;
  250. internal int _state;
  251. protected AsyncFastIterator()
  252. {
  253. _threadId = Environment.CurrentManagedThreadId;
  254. }
  255. public abstract AsyncFastIterator<T> Clone();
  256. public virtual Task DisposeAsync()
  257. {
  258. _state = -1;
  259. return Task.CompletedTask;
  260. }
  261. public IAsyncFastEnumerator<T> GetAsyncEnumerator()
  262. {
  263. AsyncFastIterator<T> enumerator = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : Clone();
  264. enumerator._state = 1;
  265. return enumerator;
  266. }
  267. public abstract Task<bool> WaitForNextAsync();
  268. public abstract T TryGetNext(out bool success);
  269. }
  270. public static class Enumerable
  271. {
  272. public static R Aggregate<T, R>(this IEnumerable<T> source, R seed, Func<R, T, R> aggregate)
  273. {
  274. var res = seed;
  275. foreach (var item in source)
  276. {
  277. res = aggregate(res, item);
  278. }
  279. return res;
  280. }
  281. public static IEnumerable<T> Empty<T>() => EmptyIterator<T>.Instance;
  282. public static void ForEach<T>(this IEnumerable<T> source, Action<T> next)
  283. {
  284. foreach (var item in source)
  285. {
  286. next(item);
  287. }
  288. }
  289. public static IEnumerable<int> Range(int start, int count) => new RangeIterator(start, count);
  290. public static IEnumerable<R> Select<T, R>(this IEnumerable<T> source, Func<T, R> selector) => new SelectIterator<T, R>(source, selector);
  291. public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) => new WhereIterator<T>(source, predicate);
  292. private sealed class EmptyIterator<T> : IEnumerable<T>, IEnumerator<T>
  293. {
  294. public static readonly EmptyIterator<T> Instance = new EmptyIterator<T>();
  295. public T Current => default(T);
  296. object IEnumerator.Current => default(T);
  297. public void Dispose() { }
  298. public IEnumerator<T> GetEnumerator() => this;
  299. public bool MoveNext() => false;
  300. public void Reset() { }
  301. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  302. }
  303. private sealed class RangeIterator : Iterator<int>
  304. {
  305. private readonly int _start;
  306. private readonly int _end;
  307. private int _next;
  308. public RangeIterator(int start, int count)
  309. {
  310. _start = start;
  311. _end = start + count;
  312. }
  313. public override Iterator<int> Clone() => new RangeIterator(_start, _end - _start);
  314. public override bool MoveNext()
  315. {
  316. switch (_state)
  317. {
  318. case 1:
  319. _next = _start;
  320. _state = 2;
  321. goto case 2;
  322. case 2:
  323. if (_next < _end)
  324. {
  325. _current = _next++;
  326. return true;
  327. }
  328. break;
  329. }
  330. return false;
  331. }
  332. }
  333. private sealed class SelectIterator<T, R> : Iterator<R>
  334. {
  335. private readonly IEnumerable<T> _source;
  336. private readonly Func<T, R> _selector;
  337. private IEnumerator<T> _enumerator;
  338. public SelectIterator(IEnumerable<T> source, Func<T, R> selector)
  339. {
  340. _source = source;
  341. _selector = selector;
  342. }
  343. public override Iterator<R> Clone() => new SelectIterator<T, R>(_source, _selector);
  344. public override bool MoveNext()
  345. {
  346. switch (_state)
  347. {
  348. case 1:
  349. _enumerator = _source.GetEnumerator();
  350. _state = 2;
  351. goto case 2;
  352. case 2:
  353. if (_enumerator.MoveNext())
  354. {
  355. _current = _selector(_enumerator.Current);
  356. return true;
  357. }
  358. break;
  359. }
  360. return false;
  361. }
  362. public override void Dispose() => _enumerator?.Dispose();
  363. }
  364. private sealed class WhereIterator<T> : Iterator<T>
  365. {
  366. private readonly IEnumerable<T> _source;
  367. private readonly Func<T, bool> _predicate;
  368. private IEnumerator<T> _enumerator;
  369. public WhereIterator(IEnumerable<T> source, Func<T, bool> predicate)
  370. {
  371. _source = source;
  372. _predicate = predicate;
  373. }
  374. public override Iterator<T> Clone() => new WhereIterator<T>(_source, _predicate);
  375. public override bool MoveNext()
  376. {
  377. switch (_state)
  378. {
  379. case 1:
  380. _enumerator = _source.GetEnumerator();
  381. _state = 2;
  382. goto case 2;
  383. case 2:
  384. while (_enumerator.MoveNext())
  385. {
  386. var item = _enumerator.Current;
  387. if (_predicate(item))
  388. {
  389. _current = item;
  390. return true;
  391. }
  392. }
  393. break;
  394. }
  395. return false;
  396. }
  397. public override void Dispose() => _enumerator?.Dispose();
  398. }
  399. }
  400. public static class FastEnumerable
  401. {
  402. public static R Aggregate<T, R>(this IFastEnumerable<T> source, R seed, Func<R, T, R> aggregate)
  403. {
  404. var res = seed;
  405. using (var e = source.GetEnumerator())
  406. {
  407. while (true)
  408. {
  409. var item = e.TryGetNext(out var success);
  410. if (!success)
  411. {
  412. break;
  413. }
  414. res = aggregate(res, item);
  415. }
  416. }
  417. return res;
  418. }
  419. public static IFastEnumerable<T> Empty<T>() => EmptyIterator<T>.Instance;
  420. public static void ForEach<T>(this IFastEnumerable<T> source, Action<T> next)
  421. {
  422. using (var e = source.GetEnumerator())
  423. {
  424. while (true)
  425. {
  426. var item = e.TryGetNext(out var success);
  427. if (!success)
  428. {
  429. break;
  430. }
  431. next(item);
  432. }
  433. }
  434. }
  435. public static IFastEnumerable<int> Range(int start, int count) => new RangeIterator(start, count);
  436. public static IFastEnumerable<R> Select<T, R>(this IFastEnumerable<T> source, Func<T, R> selector) => new SelectFastIterator<T, R>(source, selector);
  437. public static IFastEnumerable<T> ToFastEnumerable<T>(this IEnumerable<T> source) => new EnumerableToFastEnumerable<T>(source);
  438. public static IEnumerable<T> ToEnumerable<T>(this IFastEnumerable<T> source) => new FastEnumerableToEnumerable<T>(source);
  439. public static IFastEnumerable<T> Where<T>(this IFastEnumerable<T> source, Func<T, bool> predicate) => new WhereFastIterator<T>(source, predicate);
  440. private sealed class EmptyIterator<T> : IFastEnumerable<T>, IFastEnumerator<T>
  441. {
  442. public static readonly EmptyIterator<T> Instance = new EmptyIterator<T>();
  443. public void Dispose() { }
  444. public IFastEnumerator<T> GetEnumerator() => this;
  445. public T TryGetNext(out bool success)
  446. {
  447. success = false;
  448. return default(T);
  449. }
  450. }
  451. private sealed class EnumerableToFastEnumerable<T> : FastIterator<T>
  452. {
  453. private readonly IEnumerable<T> _source;
  454. private IEnumerator<T> _enumerator;
  455. public EnumerableToFastEnumerable(IEnumerable<T> source)
  456. {
  457. _source = source;
  458. }
  459. public override FastIterator<T> Clone() => new EnumerableToFastEnumerable<T>(_source);
  460. public override T TryGetNext(out bool success)
  461. {
  462. switch (_state)
  463. {
  464. case 1:
  465. _enumerator = _source.GetEnumerator();
  466. _state = 2;
  467. goto case 2;
  468. case 2:
  469. success = _enumerator.MoveNext();
  470. if (success)
  471. {
  472. return _enumerator.Current;
  473. }
  474. break;
  475. }
  476. success = false;
  477. return default(T);
  478. }
  479. public override void Dispose() => _enumerator?.Dispose();
  480. }
  481. private sealed class FastEnumerableToEnumerable<T> : Iterator<T>
  482. {
  483. private readonly IFastEnumerable<T> _source;
  484. private IFastEnumerator<T> _enumerator;
  485. public FastEnumerableToEnumerable(IFastEnumerable<T> source)
  486. {
  487. _source = source;
  488. }
  489. public override Iterator<T> Clone() => new FastEnumerableToEnumerable<T>(_source);
  490. public override bool MoveNext()
  491. {
  492. switch (_state)
  493. {
  494. case 1:
  495. _enumerator = _source.GetEnumerator();
  496. _state = 2;
  497. goto case 2;
  498. case 2:
  499. _current = _enumerator.TryGetNext(out var success);
  500. return success;
  501. }
  502. return false;
  503. }
  504. public override void Dispose() => _enumerator?.Dispose();
  505. }
  506. private sealed class RangeIterator : FastIterator<int>
  507. {
  508. private readonly int _start;
  509. private readonly int _end;
  510. private int _next;
  511. public RangeIterator(int start, int count)
  512. {
  513. _start = start;
  514. _end = start + count;
  515. }
  516. public override FastIterator<int> Clone() => new RangeIterator(_start, _end - _start);
  517. public override int TryGetNext(out bool success)
  518. {
  519. switch (_state)
  520. {
  521. case 1:
  522. _next = _start;
  523. _state = 2;
  524. goto case 2;
  525. case 2:
  526. if (_next < _end)
  527. {
  528. success = true;
  529. return _next++;
  530. }
  531. break;
  532. }
  533. success = false;
  534. return default(int);
  535. }
  536. }
  537. private sealed class SelectFastIterator<T, R> : FastIterator<R>
  538. {
  539. private readonly IFastEnumerable<T> _source;
  540. private readonly Func<T, R> _selector;
  541. private IFastEnumerator<T> _enumerator;
  542. public SelectFastIterator(IFastEnumerable<T> source, Func<T, R> selector)
  543. {
  544. _source = source;
  545. _selector = selector;
  546. }
  547. public override FastIterator<R> Clone() => new SelectFastIterator<T, R>(_source, _selector);
  548. public override R TryGetNext(out bool success)
  549. {
  550. switch (_state)
  551. {
  552. case 1:
  553. _enumerator = _source.GetEnumerator();
  554. _state = 2;
  555. goto case 2;
  556. case 2:
  557. var item = _enumerator.TryGetNext(out success);
  558. if (success)
  559. {
  560. return _selector(item);
  561. }
  562. break;
  563. }
  564. success = false;
  565. return default(R);
  566. }
  567. public override void Dispose() => _enumerator?.Dispose();
  568. }
  569. private sealed class WhereFastIterator<T> : FastIterator<T>
  570. {
  571. private readonly IFastEnumerable<T> _source;
  572. private readonly Func<T, bool> _predicate;
  573. private IFastEnumerator<T> _enumerator;
  574. public WhereFastIterator(IFastEnumerable<T> source, Func<T, bool> predicate)
  575. {
  576. _source = source;
  577. _predicate = predicate;
  578. }
  579. public override FastIterator<T> Clone() => new WhereFastIterator<T>(_source, _predicate);
  580. public override T TryGetNext(out bool success)
  581. {
  582. switch (_state)
  583. {
  584. case 1:
  585. _enumerator = _source.GetEnumerator();
  586. _state = 2;
  587. goto case 2;
  588. case 2:
  589. while (true)
  590. {
  591. var item = _enumerator.TryGetNext(out success);
  592. if (!success)
  593. {
  594. break;
  595. }
  596. if (_predicate(item))
  597. {
  598. return item;
  599. }
  600. }
  601. break;
  602. }
  603. success = false;
  604. return default(T);
  605. }
  606. public override void Dispose() => _enumerator?.Dispose();
  607. }
  608. }
  609. public static class AsyncEnumerable
  610. {
  611. private static readonly Task<bool> True = Task.FromResult(true);
  612. private static readonly Task<bool> False = Task.FromResult(false);
  613. public static async Task<R> Aggregate<T, R>(this IAsyncEnumerable<T> source, R seed, Func<R, T, R> aggregate)
  614. {
  615. var res = seed;
  616. var e = source.GetAsyncEnumerator();
  617. try
  618. {
  619. while (await e.MoveNextAsync().ConfigureAwait(false))
  620. {
  621. res = aggregate(res, e.Current);
  622. }
  623. }
  624. finally
  625. {
  626. await e.DisposeAsync().ConfigureAwait(false);
  627. }
  628. return res;
  629. }
  630. public static async Task<R> Aggregate<T, R>(this IAsyncEnumerable<T> source, R seed, Func<R, T, Task<R>> aggregate)
  631. {
  632. var res = seed;
  633. var e = source.GetAsyncEnumerator();
  634. try
  635. {
  636. while (true)
  637. {
  638. while (await e.MoveNextAsync().ConfigureAwait(false))
  639. {
  640. res = await aggregate(res, e.Current).ConfigureAwait(false);
  641. }
  642. }
  643. }
  644. finally
  645. {
  646. await e.DisposeAsync().ConfigureAwait(false);
  647. }
  648. return res;
  649. }
  650. public static IAsyncEnumerable<T> Empty<T>() => EmptyIterator<T>.Instance;
  651. public static async Task ForEachAsync<T>(this IAsyncEnumerable<T> source, Func<T, Task> next)
  652. {
  653. var e = source.GetAsyncEnumerator();
  654. try
  655. {
  656. while (await e.MoveNextAsync().ConfigureAwait(false))
  657. {
  658. var item = e.Current;
  659. await next(item).ConfigureAwait(false);
  660. }
  661. }
  662. finally
  663. {
  664. await e.DisposeAsync().ConfigureAwait(false);
  665. }
  666. }
  667. public static IAsyncEnumerable<int> Range(int start, int count) => new RangeIterator(start, count);
  668. public static IAsyncEnumerable<R> Select<T, R>(this IAsyncEnumerable<T> source, Func<T, R> selector) => new SelectIterator<T, R>(source, selector);
  669. public static IAsyncEnumerable<R> Select<T, R>(this IAsyncEnumerable<T> source, Func<T, Task<R>> selector) => new SelectIteratorWithTask<T, R>(source, selector);
  670. public static IAsyncEnumerable<T> Where<T>(this IAsyncEnumerable<T> source, Func<T, bool> predicate) => new WhereIterator<T>(source, predicate);
  671. public static IAsyncEnumerable<T> Where<T>(this IAsyncEnumerable<T> source, Func<T, Task<bool>> predicate) => new WhereIteratorWithTask<T>(source, predicate);
  672. private sealed class EmptyIterator<T> : IAsyncEnumerable<T>, IAsyncEnumerator<T>
  673. {
  674. public static readonly EmptyIterator<T> Instance = new EmptyIterator<T>();
  675. public T Current => default(T);
  676. public Task DisposeAsync() => Task.CompletedTask;
  677. public IAsyncEnumerator<T> GetAsyncEnumerator() => this;
  678. public Task<bool> MoveNextAsync() => False;
  679. }
  680. private sealed class RangeIterator : AsyncIterator<int>
  681. {
  682. private readonly int _start;
  683. private readonly int _end;
  684. private int _next;
  685. public RangeIterator(int start, int count)
  686. {
  687. _start = start;
  688. _end = start + count;
  689. }
  690. public override AsyncIterator<int> Clone() => new RangeIterator(_start, _end - _start);
  691. public override Task<bool> MoveNextAsync()
  692. {
  693. switch (_state)
  694. {
  695. case 1:
  696. _next = _start;
  697. _state = 2;
  698. goto case 2;
  699. case 2:
  700. if (_next < _end)
  701. {
  702. _current = _next++;
  703. return True;
  704. }
  705. break;
  706. }
  707. return False;
  708. }
  709. }
  710. private sealed class SelectIterator<T, R> : AsyncIterator<R>
  711. {
  712. private readonly IAsyncEnumerable<T> _source;
  713. private readonly Func<T, R> _selector;
  714. private IAsyncEnumerator<T> _enumerator;
  715. public SelectIterator(IAsyncEnumerable<T> source, Func<T, R> selector)
  716. {
  717. _source = source;
  718. _selector = selector;
  719. }
  720. public override AsyncIterator<R> Clone() => new SelectIterator<T, R>(_source, _selector);
  721. public override async Task<bool> MoveNextAsync()
  722. {
  723. switch (_state)
  724. {
  725. case 1:
  726. _enumerator = _source.GetAsyncEnumerator();
  727. _state = 2;
  728. goto case 2;
  729. case 2:
  730. if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
  731. {
  732. _current = _selector(_enumerator.Current);
  733. return true;
  734. }
  735. break;
  736. }
  737. return false;
  738. }
  739. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  740. }
  741. private sealed class SelectIteratorWithTask<T, R> : AsyncIterator<R>
  742. {
  743. private readonly IAsyncEnumerable<T> _source;
  744. private readonly Func<T, Task<R>> _selector;
  745. private IAsyncEnumerator<T> _enumerator;
  746. public SelectIteratorWithTask(IAsyncEnumerable<T> source, Func<T, Task<R>> selector)
  747. {
  748. _source = source;
  749. _selector = selector;
  750. }
  751. public override AsyncIterator<R> Clone() => new SelectIteratorWithTask<T, R>(_source, _selector);
  752. public override async Task<bool> MoveNextAsync()
  753. {
  754. switch (_state)
  755. {
  756. case 1:
  757. _enumerator = _source.GetAsyncEnumerator();
  758. _state = 2;
  759. goto case 2;
  760. case 2:
  761. if (await _enumerator.MoveNextAsync().ConfigureAwait(false))
  762. {
  763. _current = await _selector(_enumerator.Current).ConfigureAwait(false);
  764. return true;
  765. }
  766. break;
  767. }
  768. return false;
  769. }
  770. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  771. }
  772. private sealed class WhereIterator<T> : AsyncIterator<T>
  773. {
  774. private readonly IAsyncEnumerable<T> _source;
  775. private readonly Func<T, bool> _predicate;
  776. private IAsyncEnumerator<T> _enumerator;
  777. public WhereIterator(IAsyncEnumerable<T> source, Func<T, bool> predicate)
  778. {
  779. _source = source;
  780. _predicate = predicate;
  781. }
  782. public override AsyncIterator<T> Clone() => new WhereIterator<T>(_source, _predicate);
  783. public override async Task<bool> MoveNextAsync()
  784. {
  785. switch (_state)
  786. {
  787. case 1:
  788. _enumerator = _source.GetAsyncEnumerator();
  789. _state = 2;
  790. goto case 2;
  791. case 2:
  792. while (await _enumerator.MoveNextAsync().ConfigureAwait(false))
  793. {
  794. var item = _enumerator.Current;
  795. if (_predicate(item))
  796. {
  797. _current = item;
  798. return true;
  799. }
  800. }
  801. break;
  802. }
  803. return false;
  804. }
  805. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  806. }
  807. private sealed class WhereIteratorWithTask<T> : AsyncIterator<T>
  808. {
  809. private readonly IAsyncEnumerable<T> _source;
  810. private readonly Func<T, Task<bool>> _predicate;
  811. private IAsyncEnumerator<T> _enumerator;
  812. public WhereIteratorWithTask(IAsyncEnumerable<T> source, Func<T, Task<bool>> predicate)
  813. {
  814. _source = source;
  815. _predicate = predicate;
  816. }
  817. public override AsyncIterator<T> Clone() => new WhereIteratorWithTask<T>(_source, _predicate);
  818. public override async Task<bool> MoveNextAsync()
  819. {
  820. switch (_state)
  821. {
  822. case 1:
  823. _enumerator = _source.GetAsyncEnumerator();
  824. _state = 2;
  825. goto case 2;
  826. case 2:
  827. while (await _enumerator.MoveNextAsync().ConfigureAwait(false))
  828. {
  829. var item = _enumerator.Current;
  830. if (await _predicate(item).ConfigureAwait(false))
  831. {
  832. _current = item;
  833. return true;
  834. }
  835. }
  836. break;
  837. }
  838. return false;
  839. }
  840. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  841. }
  842. }
  843. public static class AsyncFastEnumerable
  844. {
  845. private static readonly Task<bool> True = Task.FromResult(true);
  846. private static readonly Task<bool> False = Task.FromResult(false);
  847. public static async Task<R> Aggregate<T, R>(this IAsyncFastEnumerable<T> source, R seed, Func<R, T, R> aggregate)
  848. {
  849. var res = seed;
  850. var e = source.GetAsyncEnumerator();
  851. try
  852. {
  853. while (await e.WaitForNextAsync().ConfigureAwait(false))
  854. {
  855. while (true)
  856. {
  857. var item = e.TryGetNext(out var success);
  858. if (!success)
  859. {
  860. break;
  861. }
  862. res = aggregate(res, item);
  863. }
  864. }
  865. }
  866. finally
  867. {
  868. await e.DisposeAsync().ConfigureAwait(false);
  869. }
  870. return res;
  871. }
  872. public static async Task<R> Aggregate<T, R>(this IAsyncFastEnumerable<T> source, R seed, Func<R, T, Task<R>> aggregate)
  873. {
  874. var res = seed;
  875. var e = source.GetAsyncEnumerator();
  876. try
  877. {
  878. while (await e.WaitForNextAsync().ConfigureAwait(false))
  879. {
  880. while (true)
  881. {
  882. var item = e.TryGetNext(out var success);
  883. if (!success)
  884. {
  885. break;
  886. }
  887. res = await aggregate(res, item).ConfigureAwait(false);
  888. }
  889. }
  890. }
  891. finally
  892. {
  893. await e.DisposeAsync().ConfigureAwait(false);
  894. }
  895. return res;
  896. }
  897. public static IAsyncFastEnumerable<T> Empty<T>() => EmptyIterator<T>.Instance;
  898. public static async Task ForEachAsync<T>(this IAsyncFastEnumerable<T> source, Func<T, Task> next)
  899. {
  900. var e = source.GetAsyncEnumerator();
  901. try
  902. {
  903. while (await e.WaitForNextAsync().ConfigureAwait(false))
  904. {
  905. while (true)
  906. {
  907. var item = e.TryGetNext(out var success);
  908. if (!success)
  909. {
  910. break;
  911. }
  912. await next(item).ConfigureAwait(false);
  913. }
  914. }
  915. }
  916. finally
  917. {
  918. await e.DisposeAsync().ConfigureAwait(false);
  919. }
  920. }
  921. public static IAsyncFastEnumerable<int> Range(int start, int count) => new RangeIterator(start, count);
  922. public static IAsyncFastEnumerable<R> Select<T, R>(this IAsyncFastEnumerable<T> source, Func<T, R> selector) => new SelectFastIterator<T, R>(source, selector);
  923. public static IAsyncFastEnumerable<R> Select<T, R>(this IAsyncFastEnumerable<T> source, Func<T, Task<R>> selector) => new SelectFastIteratorWithTask<T, R>(source, selector);
  924. public static IAsyncFastEnumerable<T> ToAsyncFastEnumerable<T>(this IAsyncEnumerable<T> source) => new AsyncEnumerableToAsyncFastEnumerable<T>(source);
  925. public static IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IAsyncFastEnumerable<T> source) => new AsyncFastEnumerableToAsyncEnumerable<T>(source);
  926. public static IAsyncFastEnumerable<T> Where<T>(this IAsyncFastEnumerable<T> source, Func<T, bool> predicate) => new WhereFastIterator<T>(source, predicate);
  927. public static IAsyncFastEnumerable<T> Where<T>(this IAsyncFastEnumerable<T> source, Func<T, Task<bool>> predicate) => new WhereFastIteratorWithTask<T>(source, predicate);
  928. private sealed class EmptyIterator<T> : IAsyncFastEnumerable<T>, IAsyncFastEnumerator<T>
  929. {
  930. public static readonly EmptyIterator<T> Instance = new EmptyIterator<T>();
  931. public Task DisposeAsync() => Task.CompletedTask;
  932. public IAsyncFastEnumerator<T> GetAsyncEnumerator() => this;
  933. public T TryGetNext(out bool success)
  934. {
  935. success = false;
  936. return default(T);
  937. }
  938. public Task<bool> WaitForNextAsync() => False;
  939. }
  940. private sealed class AsyncEnumerableToAsyncFastEnumerable<T> : AsyncFastIterator<T>
  941. {
  942. private readonly IAsyncEnumerable<T> _source;
  943. private IAsyncEnumerator<T> _enumerator;
  944. private bool _hasNext;
  945. public AsyncEnumerableToAsyncFastEnumerable(IAsyncEnumerable<T> source)
  946. {
  947. _source = source;
  948. }
  949. public override AsyncFastIterator<T> Clone() => new AsyncEnumerableToAsyncFastEnumerable<T>(_source);
  950. public override T TryGetNext(out bool success)
  951. {
  952. success = _hasNext;
  953. _hasNext = false;
  954. return success ? _enumerator.Current : default(T);
  955. }
  956. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  957. public override async Task<bool> WaitForNextAsync()
  958. {
  959. switch (_state)
  960. {
  961. case 1:
  962. _enumerator = _source.GetAsyncEnumerator();
  963. _state = 2;
  964. goto case 2;
  965. case 2:
  966. _hasNext = await _enumerator.MoveNextAsync().ConfigureAwait(false);
  967. return _hasNext;
  968. }
  969. return false;
  970. }
  971. }
  972. private sealed class AsyncFastEnumerableToAsyncEnumerable<T> : AsyncIterator<T>
  973. {
  974. private readonly IAsyncFastEnumerable<T> _source;
  975. private IAsyncFastEnumerator<T> _enumerator;
  976. public AsyncFastEnumerableToAsyncEnumerable(IAsyncFastEnumerable<T> source)
  977. {
  978. _source = source;
  979. }
  980. public override AsyncIterator<T> Clone() => new AsyncFastEnumerableToAsyncEnumerable<T>(_source);
  981. public override async Task<bool> MoveNextAsync()
  982. {
  983. switch (_state)
  984. {
  985. case 1:
  986. _enumerator = _source.GetAsyncEnumerator();
  987. _state = 2;
  988. goto case 2;
  989. case 2:
  990. do
  991. {
  992. while (true)
  993. {
  994. var item = _enumerator.TryGetNext(out var success);
  995. if (!success)
  996. {
  997. break;
  998. }
  999. else
  1000. {
  1001. _current = item;
  1002. return true;
  1003. }
  1004. }
  1005. } while (await _enumerator.WaitForNextAsync().ConfigureAwait(false));
  1006. break;
  1007. }
  1008. return false;
  1009. }
  1010. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  1011. }
  1012. private sealed class RangeIterator : AsyncFastIterator<int>
  1013. {
  1014. private readonly int _start;
  1015. private readonly int _end;
  1016. private int _next;
  1017. public RangeIterator(int start, int count)
  1018. {
  1019. _start = start;
  1020. _end = start + count;
  1021. }
  1022. public override AsyncFastIterator<int> Clone() => new RangeIterator(_start, _end - _start);
  1023. public override int TryGetNext(out bool success)
  1024. {
  1025. if (_state == 2 && _next < _end)
  1026. {
  1027. success = true;
  1028. return _next++;
  1029. }
  1030. success = false;
  1031. return default(int);
  1032. }
  1033. public override Task<bool> WaitForNextAsync()
  1034. {
  1035. switch (_state)
  1036. {
  1037. case 1:
  1038. _next = _start;
  1039. _state = 2;
  1040. goto case 2;
  1041. case 2:
  1042. if (_next < _end)
  1043. {
  1044. return True;
  1045. }
  1046. break;
  1047. }
  1048. return False;
  1049. }
  1050. }
  1051. private sealed class SelectFastIterator<T, R> : AsyncFastIterator<R>
  1052. {
  1053. private readonly IAsyncFastEnumerable<T> _source;
  1054. private readonly Func<T, R> _selector;
  1055. private IAsyncFastEnumerator<T> _enumerator;
  1056. public SelectFastIterator(IAsyncFastEnumerable<T> source, Func<T, R> selector)
  1057. {
  1058. _source = source;
  1059. _selector = selector;
  1060. }
  1061. public override AsyncFastIterator<R> Clone() => new SelectFastIterator<T, R>(_source, _selector);
  1062. public override R TryGetNext(out bool success)
  1063. {
  1064. if (_enumerator != null)
  1065. {
  1066. var item = _enumerator.TryGetNext(out success);
  1067. if (success)
  1068. {
  1069. return _selector(item);
  1070. }
  1071. }
  1072. success = false;
  1073. return default(R);
  1074. }
  1075. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  1076. public override Task<bool> WaitForNextAsync()
  1077. {
  1078. switch (_state)
  1079. {
  1080. case 1:
  1081. _enumerator = _source.GetAsyncEnumerator();
  1082. _state = 2;
  1083. goto case 2;
  1084. case 2:
  1085. return _enumerator.WaitForNextAsync();
  1086. }
  1087. return False;
  1088. }
  1089. }
  1090. private sealed class SelectFastIteratorWithTask<T, R> : AsyncFastIterator<R>
  1091. {
  1092. private readonly IAsyncFastEnumerable<T> _source;
  1093. private readonly Func<T, Task<R>> _selector;
  1094. private IAsyncFastEnumerator<T> _enumerator;
  1095. private bool _hasNext;
  1096. private R _next;
  1097. public SelectFastIteratorWithTask(IAsyncFastEnumerable<T> source, Func<T, Task<R>> selector)
  1098. {
  1099. _source = source;
  1100. _selector = selector;
  1101. }
  1102. public override AsyncFastIterator<R> Clone() => new SelectFastIteratorWithTask<T, R>(_source, _selector);
  1103. public override R TryGetNext(out bool success)
  1104. {
  1105. success = _hasNext;
  1106. _hasNext = false;
  1107. return success ? _next : default(R);
  1108. }
  1109. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  1110. public override async Task<bool> WaitForNextAsync()
  1111. {
  1112. switch (_state)
  1113. {
  1114. case 1:
  1115. _enumerator = _source.GetAsyncEnumerator();
  1116. _state = 2;
  1117. goto case 2;
  1118. case 2:
  1119. do
  1120. {
  1121. while (true)
  1122. {
  1123. var item = _enumerator.TryGetNext(out var success);
  1124. if (!success)
  1125. {
  1126. break;
  1127. }
  1128. else
  1129. {
  1130. _hasNext = true;
  1131. _next = await _selector(item).ConfigureAwait(false);
  1132. return true;
  1133. }
  1134. }
  1135. }
  1136. while (await _enumerator.WaitForNextAsync().ConfigureAwait(false));
  1137. break;
  1138. }
  1139. _hasNext = false;
  1140. _next = default(R);
  1141. return false;
  1142. }
  1143. }
  1144. private sealed class WhereFastIterator<T> : AsyncFastIterator<T>
  1145. {
  1146. private readonly IAsyncFastEnumerable<T> _source;
  1147. private readonly Func<T, bool> _predicate;
  1148. private IAsyncFastEnumerator<T> _enumerator;
  1149. public WhereFastIterator(IAsyncFastEnumerable<T> source, Func<T, bool> predicate)
  1150. {
  1151. _source = source;
  1152. _predicate = predicate;
  1153. }
  1154. public override AsyncFastIterator<T> Clone() => new WhereFastIterator<T>(_source, _predicate);
  1155. public override T TryGetNext(out bool success)
  1156. {
  1157. if (_enumerator != null)
  1158. {
  1159. while (true)
  1160. {
  1161. var item = _enumerator.TryGetNext(out success);
  1162. if (!success)
  1163. {
  1164. break;
  1165. }
  1166. if (_predicate(item))
  1167. {
  1168. return item;
  1169. }
  1170. }
  1171. }
  1172. success = false;
  1173. return default(T);
  1174. }
  1175. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  1176. public override Task<bool> WaitForNextAsync()
  1177. {
  1178. switch (_state)
  1179. {
  1180. case 1:
  1181. _enumerator = _source.GetAsyncEnumerator();
  1182. _state = 2;
  1183. goto case 2;
  1184. case 2:
  1185. return _enumerator.WaitForNextAsync();
  1186. }
  1187. return False;
  1188. }
  1189. }
  1190. private sealed class WhereFastIteratorWithTask<T> : AsyncFastIterator<T>
  1191. {
  1192. private readonly IAsyncFastEnumerable<T> _source;
  1193. private readonly Func<T, Task<bool>> _predicate;
  1194. private IAsyncFastEnumerator<T> _enumerator;
  1195. private bool _hasNext;
  1196. private T _next;
  1197. public WhereFastIteratorWithTask(IAsyncFastEnumerable<T> source, Func<T, Task<bool>> predicate)
  1198. {
  1199. _source = source;
  1200. _predicate = predicate;
  1201. }
  1202. public override AsyncFastIterator<T> Clone() => new WhereFastIteratorWithTask<T>(_source, _predicate);
  1203. public override T TryGetNext(out bool success)
  1204. {
  1205. success = _hasNext;
  1206. _hasNext = false;
  1207. return success ? _next : default(T);
  1208. }
  1209. public override Task DisposeAsync() => _enumerator?.DisposeAsync() ?? Task.CompletedTask;
  1210. public override async Task<bool> WaitForNextAsync()
  1211. {
  1212. switch (_state)
  1213. {
  1214. case 1:
  1215. _enumerator = _source.GetAsyncEnumerator();
  1216. _state = 2;
  1217. goto case 2;
  1218. case 2:
  1219. do
  1220. {
  1221. while (true)
  1222. {
  1223. var item = _enumerator.TryGetNext(out var success);
  1224. if (!success)
  1225. {
  1226. break;
  1227. }
  1228. else
  1229. {
  1230. if (await _predicate(item).ConfigureAwait(false))
  1231. {
  1232. _hasNext = true;
  1233. _next = item;
  1234. return true;
  1235. }
  1236. }
  1237. }
  1238. }
  1239. while (await _enumerator.WaitForNextAsync().ConfigureAwait(false));
  1240. break;
  1241. }
  1242. _hasNext = false;
  1243. _next = default(T);
  1244. return false;
  1245. }
  1246. }
  1247. }
  1248. }