From 6525e1d70704af9eb4b215abb3bfcf53b7d6cba7 Mon Sep 17 00:00:00 2001 From: Orace Date: Thu, 31 Oct 2019 18:46:21 +0100 Subject: [PATCH 1/3] Fix #625 TagFirstLast is not optimal in memory --- MoreLinq/TagFirstLast.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/MoreLinq/TagFirstLast.cs b/MoreLinq/TagFirstLast.cs index f22d3fbbf..ce32738c7 100644 --- a/MoreLinq/TagFirstLast.cs +++ b/MoreLinq/TagFirstLast.cs @@ -60,8 +60,21 @@ public static IEnumerable TagFirstLast(this IEnumerab if (source == null) throw new ArgumentNullException(nameof(source)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return source.Index() // count-up - .CountDown(1, (e, cd) => resultSelector(e.Value, e.Key == 0, cd == 0)); + using var enumerator = source.GetEnumerator(); + + if (!enumerator.MoveNext()) + yield break; + + var current = enumerator.Current; + var hasNext = enumerator.MoveNext(); + yield return resultSelector(current, true, !hasNext); + + while (hasNext) + { + current = enumerator.Current; + hasNext = enumerator.MoveNext(); + yield return resultSelector(current, false, !hasNext); + } } } } From 9a1b2bdebe33d285d53775d9b2cd4bc12e0977a1 Mon Sep 17 00:00:00 2001 From: Orace Date: Thu, 31 Oct 2019 18:56:37 +0100 Subject: [PATCH 2/3] Fix trailing whitespace --- MoreLinq/TagFirstLast.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MoreLinq/TagFirstLast.cs b/MoreLinq/TagFirstLast.cs index ce32738c7..80cc7729c 100644 --- a/MoreLinq/TagFirstLast.cs +++ b/MoreLinq/TagFirstLast.cs @@ -68,7 +68,7 @@ public static IEnumerable TagFirstLast(this IEnumerab var current = enumerator.Current; var hasNext = enumerator.MoveNext(); yield return resultSelector(current, true, !hasNext); - + while (hasNext) { current = enumerator.Current; From 30e119c6aa1ee4ef4c970e709e93c647c0d721e1 Mon Sep 17 00:00:00 2001 From: Orace Date: Thu, 31 Oct 2019 19:08:34 +0100 Subject: [PATCH 3/3] Avoid to defer the argument validation in TagFirstLast --- MoreLinq/TagFirstLast.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/MoreLinq/TagFirstLast.cs b/MoreLinq/TagFirstLast.cs index 80cc7729c..2ffb5c9a3 100644 --- a/MoreLinq/TagFirstLast.cs +++ b/MoreLinq/TagFirstLast.cs @@ -60,20 +60,23 @@ public static IEnumerable TagFirstLast(this IEnumerab if (source == null) throw new ArgumentNullException(nameof(source)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - using var enumerator = source.GetEnumerator(); + return _(); IEnumerable _() + { + using var enumerator = source.GetEnumerator(); - if (!enumerator.MoveNext()) - yield break; + if (!enumerator.MoveNext()) + yield break; - var current = enumerator.Current; - var hasNext = enumerator.MoveNext(); - yield return resultSelector(current, true, !hasNext); + var current = enumerator.Current; + var hasNext = enumerator.MoveNext(); + yield return resultSelector(current, true, !hasNext); - while (hasNext) - { - current = enumerator.Current; - hasNext = enumerator.MoveNext(); - yield return resultSelector(current, false, !hasNext); + while (hasNext) + { + current = enumerator.Current; + hasNext = enumerator.MoveNext(); + yield return resultSelector(current, false, !hasNext); + } } } }