C# 如何在Linq Where子句中利用动态编程?
我正在试图找到一种方法来传递或使用.Where子句中的集合以加快执行,但没有任何运气。以下是我想做的:C# 如何在Linq Where子句中利用动态编程?,c#,.net,linq,dynamic-programming,C#,.net,Linq,Dynamic Programming,我正在试图找到一种方法来传递或使用.Where子句中的集合以加快执行,但没有任何运气。以下是我想做的: var matches = superLongEnumerable.Where((x, HashSet<string> dynamicSet) => { var parent = SemiExpensiveCallToGetParent(x); if(dynamicSet.Contains(parent)) {
var matches = superLongEnumerable.Where((x, HashSet<string> dynamicSet) =>
{
var parent = SemiExpensiveCallToGetParent(x);
if(dynamicSet.Contains(parent))
{
// DP optimization to save further computation
return true;
}
var matched = ExpensiveCallToCheckMatch(parent);
if(matched) {
dynamicSet.Add(parent);
}
return matched;
});
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
据我所知,.Where只支持当前元素,并且可选地支持当前元素的索引。是否有一个替代。我可以在何处使用?如果它与您的matches变量在同一范围内可见,您可以使用它,而不必传入它。如果在调用Where的外部定义了dynamicSet变量,只需使用Wherex=>。。。。您不需要传入它。如果它与matches变量在同一范围内可见,您可以使用它而无需传入它。如果在调用Where的外部定义了dynamicSet变量,只需使用Wherex=>。。。。您不需要将其传入。因为这显然是LINQ to entities,所以您可以始终为简单场景创建一个简单的for或foreach,或者构建一个枚举器函数
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
但性能方面的主要问题是:您只保存昂贵测试的结果,如果成功,您会反复重复不成功的昂贵呼叫。
所以字典可能更有用
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
另一种选择是
public IEnumerable<string> MyFilter(IEnumerable<string> source)
{
var temp = new Dictionary<string, bool>();
foreach(var item in source)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
{
if (result)
yield return item;
}
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
if (matched)
yield return item;
}
}
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
再次强调:这只是LINQ到实体,而不是LINQ到SQL
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
并将首选的StringComparer放入字典的构造函数调用中。因为这是LINQ to entities,显然,您可以始终为简单场景创建一个简单的for或foreach,或者构建一个枚举器函数
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
但性能方面的主要问题是:您只保存昂贵测试的结果,如果成功,您会反复重复不成功的昂贵呼叫。
所以字典可能更有用
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
另一种选择是
public IEnumerable<string> MyFilter(IEnumerable<string> source)
{
var temp = new Dictionary<string, bool>();
foreach(var item in source)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
{
if (result)
yield return item;
}
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
if (matched)
yield return item;
}
}
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
再次强调:这只是LINQ到实体,而不是LINQ到SQL
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}
并将首选的StringComparer放入字典的构造函数调用中
public class Helper
{
private readonly Dictionary<string,bool> tmp = new Dictionary<string, bool>();
public bool Condition(string item)
{
var parent = SemiExpensiveCallToGetParent(item);
if (temp.TryGetValue(parent, out bool result))
return result;
var matched = ExpensiveCallToCheckMatch(parent);
temp.Add(parent, matched);
return matched;
}
}