From cad2ec3a0966f2e39139a5cb35bae514287d4c7b Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Mon, 9 Jan 2017 01:12:49 +0000 Subject: [PATCH] Reduce enumeration of rightResults in BooleanQueryExpression.IsMatch (#1155) If Operator is Exists or leftResults is empty don't obtain rightResults, as not relevant. Otherwise if rightResults is not an ICollection load it into an List so it won't be recomputed on each enumeration of leftResults. --- .../Linq/JsonPath/QueryExpression.cs | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs b/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs index 1139d559..ed666842 100644 --- a/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs +++ b/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs @@ -2,6 +2,11 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq.JsonPath @@ -88,24 +93,29 @@ namespace Newtonsoft.Json.Linq.JsonPath public override bool IsMatch(JToken root, JToken t) { - IEnumerable rightResults = GetResult(root, t, Right); - IEnumerable leftResults = GetResult(root, t, Left); - - foreach (JToken leftResult in leftResults) + if (Operator == QueryOperator.Exists) { - if (Operator == QueryOperator.Exists) + return GetResult(root, t, Left).Any(); + } + + using (IEnumerator leftResults = GetResult(root, t, Left).GetEnumerator()) + { + if (leftResults.MoveNext()) { - return true; - } - else - { - foreach (JToken rightResult in rightResults) + IEnumerable rightResultsEn = GetResult(root, t, Right); + ICollection rightResults = rightResultsEn as ICollection ?? rightResultsEn.ToList(); + + do { - if (MatchTokens(leftResult, rightResult)) + JToken leftResult = leftResults.Current; + foreach (JToken rightResult in rightResults) { - return true; + if (MatchTokens(leftResult, rightResult)) + { + return true; + } } - } + } while (leftResults.MoveNext()); } }