C# 使用Array.Contains提高Lambda的性能?
我有这个功能,我想提高性能。瓶颈出现在创建选择的末尾,可能与Contains()函数有关。我不知道有什么更有效的方法来进行选择:C# 使用Array.Contains提高Lambda的性能?,c#,linq,lambda,C#,Linq,Lambda,我有这个功能,我想提高性能。瓶颈出现在创建选择的末尾,可能与Contains()函数有关。我不知道有什么更有效的方法来进行选择: public static Dictionary<string, SubItem> SubItemCache = new Dictionary<string, SubItem>(); public static Dictionary<string, Item> ItemCache = new Dictionary<string
public static Dictionary<string, SubItem> SubItemCache = new Dictionary<string, SubItem>();
public static Dictionary<string, Item> ItemCache = new Dictionary<string, Item>();
private static IEnumerable<Item> GetSimilarItems(int days, string type,
float counterOne, float counterTwo)
{
string[] similarSubItems;
if (days > 180)
{
similarSubItems = SubItemCache.Values
.Where(p => p.CounterOne >= counterOne * 0.9
&& p.CounterOne <= counterOne * 1.1)
.Select(o => o.ID).ToArray();
}
else
{
similarSubItems = SubItemCache.Values
.Where(p => p.CounterTwo >= counterTwo * 0.9
&& p.CounterTwo <= counterTwo * 1.1)
.Select(o => o.ID).ToArray();
}
var selection = ItemCache.Values.Where(p => p.days >= days - 5 && p.days <= days + 5
&& p.Type == type
&& similarSubItems.Contains(p.Key));
return selection;
}
publicstaticdictionary SubItemCache=newdictionary();
public static Dictionary ItemCache=new Dictionary();
私有静态IEnumerable GetSimilarItems(整数天,字符串类型,
浮动计数器1,浮动计数器2)
{
字符串[]相似的子项;
如果(天数>180天)
{
similarSubItems=SubItemCache.Values
其中(p=>p.CounterOne>=CounterOne*0.9
&&p.CounterOne o.ID.)ToArray();
}
其他的
{
similarSubItems=SubItemCache.Values
其中(p=>p.CounterTwo>=CounterTwo*0.9
&&p.计数器(两个外径)。ToArray();
}
var selection=ItemCache.Values.Where(p=>p.days>=days-5&&p.days取决于它的大小,用HashSet
交换字符串[]
,并使用.Contains
方法。它将有更快的查找时间
上一次测试时,我发现如果将直接查找与构建哈希集+查找的开销进行比较,集合中大约有15个项目的查找时间比哈希集快
public static Dictionary<string, SubItem> SubItemCache = new Dictionary<string, SubItem>();
public static Dictionary<string, Item> ItemCache = new Dictionary<string, Item>();
private static IEnumerable<Item> GetSimilarItems(int days, string type,
float counterOne, float counterTwo)
{
HashSet<string> similarSubItems;
if (days > 180)
{
similarSubItems = new HashSet<string>(SubItemCache.Values
.Where(p => p.CounterOne >= counterOne * 0.9
&& p.CounterOne <= counterOne * 1.1)
.Select(o => o.ID));
}
else
{
similarSubItems = new HashSet<string>(SubItemCache.Values
.Where(p => p.CounterTwo >= counterTwo * 0.9
&& p.CounterTwo <= counterTwo * 1.1)
.Select(o => o.ID));
}
var selection = ItemCache.Values.Where(p => p.days >= days - 5 && p.days <= days + 5
&& p.Type == type
&& similarSubItems.Contains(p.Key));
return selection;
}
publicstaticdictionary SubItemCache=newdictionary();
public static Dictionary ItemCache=new Dictionary();
私有静态IEnumerable GetSimilarItems(整数天,字符串类型,
浮动计数器1,浮动计数器2)
{
散列集相似项;
如果(天数>180天)
{
similarSubItems=新哈希集(SubItemCache.Values
其中(p=>p.CounterOne>=CounterOne*0.9
&&p.CounterOne o.ID));
}
其他的
{
similarSubItems=新哈希集(SubItemCache.Values
其中(p=>p.CounterTwo>=CounterTwo*0.9
&&p.o.ID));
}
var selection=ItemCache.Values.Where(p=>p.days>=days-5&&p.days我想不出任何简单的方法,但作为最后的手段,您应该能够通过避免LINQ和lambda开销,再节省大约20%:
private static IEnumerable<Item> GetSimilarItems(int days, string type,
float counterOne, float counterTwo)
{
var similarSubItems = new HashSet<string>();
var c9 = counterOne * 0.9;
var c1 = counterOne * 1.1;
if (days > 180)
{
foreach (var p in SubItemCache.Values)
if (p.CounterOne >= c9 && p.CounterOne <= c1)
similarSubItems.Add(p.ID);
}
else
{
foreach (var p in SubItemCache.Values)
if (p.CounterTwo >= c9 && p.CounterTwo <= c1)
similarSubItems.Add(p.ID);
}
var days0 = days - 5;
var days1 = days + 5;
foreach (var p in ItemCache.Values)
if (p.days >= days0 && p.days <= days1
&& p.Type == type && similarSubItems.Contains(p.Key))
yield return p;
}
私有静态IEnumerable GetSimilarItems(整数天,字符串类型,
浮动计数器1,浮动计数器2)
{
var similarSubItems=new HashSet();
var c9=反一*0.9;
var c1=反向1*1.1;
如果(天数>180天)
{
foreach(SubItemCache.Values中的var p)
如果(p.CounterOne>=c9&&p.CounterOne=c9&&p.CounterTwo=days0&&p.days如果函数的结果被多次枚举,则返回列表或数组,而不是不同的执行IEnumerableThanks作为提示。如果我理解正确,通过“枚举多次”这意味着,如果我想对结果执行多个foreach,或者使用.Where子句进行进一步筛选…?目前我只使用结果对其执行单个foreach。在定义时不执行返回IEnumerable的LINQ扩展,而是在foreach
,Count()中需要结果时执行
,。ToArray
,等等。如果您只在foreach中使用结果,则可以保持原样。收到了,非常感谢!非常感谢。似乎性能提高了20%左右!非常感谢!就像您所说的,性能提高了更多。