From 1829b71255e3e08530c654ac213da3f4ae49cf07 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 14:51:49 +0000 Subject: [PATCH 1/8] Optimise LinqBridge.Enumerable.Cast for direct cast available. (This changes the behaviour to return same type, but framework Linq has the same optimisation). --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index f24636f8..b5bdc1ba 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -72,7 +72,14 @@ namespace Newtonsoft.Json.Utilities.LinqBridge { CheckNotNull(source, "source"); - return CastYield(source); + var servesItself = source as IEnumerable; + if (servesItself != null + && (!(servesItself is TResult[]) || servesItself.GetType().GetElementType() == typeof(TResult))) + { + return servesItself; + } + + return CastYield(source); } private static IEnumerable CastYield( From 5bd4521b532b778946cd606ef078f232919838f0 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 14:53:16 +0000 Subject: [PATCH 2/8] Load stack for Reverse using enumerable-taking ctor --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index b5bdc1ba..2777b418 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -619,9 +619,7 @@ namespace Newtonsoft.Json.Utilities.LinqBridge private static IEnumerable ReverseYield(IEnumerable source) { - var stack = new Stack(); - foreach (var item in source) - stack.Push(item); + var stack = new Stack(source); foreach (var item in stack) yield return item; From e08d1f752462260837445399626bba3b09f31f75 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 15:01:48 +0000 Subject: [PATCH 3/8] Optimise ToArray for list source --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index 2777b418..f2327289 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -793,17 +793,25 @@ namespace Newtonsoft.Json.Utilities.LinqBridge return new List(source); } - /// - /// Creates an array from an . - /// + /// + /// Creates an array from an . + /// - public static TSource[] ToArray( - this IEnumerable source) - { - return source.ToList().ToArray(); - } + public static TSource[] ToArray( + this IEnumerable source) + { + IList ilist = source as IList; + if (ilist != null) + { + TSource[] array = new TSource[ilist.Count]; + ilist.CopyTo(array, 0); + return array; + } - /// + return source.ToList().ToArray(); + } + + /// /// Returns distinct elements from a sequence by using the default /// equality comparer to compare values. /// From dbc7374995f70820b21355fa1db03c62c10df56c Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 15:17:22 +0000 Subject: [PATCH 4/8] Optimise LinqBridge Count --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index f2327289..3c862729 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -711,9 +711,21 @@ namespace Newtonsoft.Json.Utilities.LinqBridge CheckNotNull(source, "source"); var collection = source as ICollection; - return collection != null - ? collection.Count - : source.Aggregate(0, (count, item) => checked(count + 1)); + if (collection != null) + { + return collection.Count; + } + + using (var en = source.GetEnumerator()) + { + int count = 0; + while (en.MoveNext()) + { + ++count; + } + + return count; + } } /// From 32d8b4a68a6d1848c3268be5c4bb34a9fa5d5ee5 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 15:45:06 +0000 Subject: [PATCH 5/8] Optimise LinqBridge Any --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index 3c862729..378fd1dc 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -1246,7 +1246,15 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func predicate) { - return source.Where(predicate).Any(); + foreach (TSource item in source) + { + if (predicate(item)) + { + return true; + } + } + + return false; } /// From c003ad0d9893d9d178a403fc5eacf53926f0ed5d Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 15:45:48 +0000 Subject: [PATCH 6/8] Optimise decimal predicate sum --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index 378fd1dc..15beffe7 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -1248,7 +1248,7 @@ namespace Newtonsoft.Json.Utilities.LinqBridge { foreach (TSource item in source) { - if (predicate(item)) + if (predicate(item)) { return true; } @@ -2579,7 +2579,16 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func selector) { - return source.Select(selector).Sum(); + CheckNotNull(source, "source"); + CheckNotNull(selector, "selector"); + + decimal sum = 0; + foreach (TSource item in source) + { + sum += selector(item); + } + + return sum; } /// From 896448860a779c7ad4ea657085291154d4576e84 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 15:48:12 +0000 Subject: [PATCH 7/8] Optimise LinqBridge.Enumerable.Where --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index 15beffe7..786a547b 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -158,11 +158,20 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func predicate) { + CheckNotNull(source, "source"); CheckNotNull(predicate, "predicate"); - return source.Where((item, i) => predicate(item)); + return WhereYield(source, predicate); } + private static IEnumerable WhereYield( + IEnumerable source, + Func predicate) + { + foreach (var item in source) + if (predicate(item)) + yield return item; + } /// /// Filters a sequence of values based on a predicate. /// Each element's index is used in the logic of the predicate function. From f5c64fdd09c44eb27527a235c69688fac6a69bd1 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Wed, 4 Jan 2017 16:20:58 +0000 Subject: [PATCH 8/8] Optimise linqbridge Select --- Src/Newtonsoft.Json/Utilities/LinqBridge.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index 786a547b..d151069f 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -205,9 +205,18 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func selector) { + CheckNotNull(source, "source"); CheckNotNull(selector, "selector"); - return source.Select((item, i) => selector(item)); + return SelectYield(source, selector); + } + + private static IEnumerable SelectYield( + IEnumerable source, + Func selector) + { + foreach (var item in source) + yield return selector(item); } ///