[英]Performance improvement for Lambda using Array.Contains?
I have this function and I want to improve the performance. 我有此功能,我想提高性能。 The bottleneck is at the end when selection is created and has probably to do with the Contains() function.
创建选择时,瓶颈就在最后,可能与Contains()函数有关。 I don't know a more efficient way to do that selection:
我不知道一种更有效的选择方法:
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;
}
Is there a way to improve the function performance wise? 有没有办法明智地提高功能性能?
Depending on it's size, swap out the string[]
with a HashSet<string>
and use the .Contains
method on that. 根据其大小,将
HashSet<string>
替换为string[]
并在.Contains
上使用.Contains
方法。 It will have significantly faster lookup times. 查找时间将大大缩短。
Last time I tested, i found that around 15 items in the collection is when you had faster lookup times with a Hash Set if you compared a straight lookup vs the overhead of building the Hash Set + the lookup. 上次我测试时,我发现如果将直接查找与构建哈希集+查找的开销进行比较,则使用哈希集可以更快地查找集合中的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;
}
I can't think of anything simple, but as a final resort you should be able to save another about 20% by avoiding the LINQ and lambda overhead: 我想不出任何简单的方法,但是作为最后的选择,您应该能够避免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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.