Program.cs 49 KB

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