我要根据某些逻辑执行一些收集和返回排名 我希望优化这个工作代码,因为我认为它可以更好(可能使用任务?)
这是执行搜索的代码和扩展方法
public class Counterpart
{
public int Id { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public IEnumerable<Alias> Aliases { get; set; }
public override bool Equals(object obj)
{
Counterpart obj2 = obj as Counterpart;
if (obj2 == null) return false;
return Id == obj2.Id;
}
}
public class Alias
{
public int? Type { get; set; }
public string Description { get; set; }
}
internal class CounterPartRanking
{
public int Rank { get; set; }
public Counterpart CounterPart { get; set; }
}
public static class CounterpartExtensions
{
public static IEnumerable<Counterpart> SearchWithRank(this IEnumerable<Counterpart> source, string pattern)
{
var items1 = source.Where(x => x.Code == pattern);
var items2 = source.Where(x => x.Code.StartsWith(pattern));
var items3 = source.Where(x => x.Code.Contains(pattern));
var items4 = source.Where(x => x.Description.Contains(pattern));
var items5 = source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description == pattern));
var items6 = source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description.StartsWith(pattern)));
var items7 = source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description.Contains(pattern)));
Stopwatch sw = Stopwatch.StartNew();
var rankedItems = new List<CounterPartRanking>();
if (items1.Any())
rankedItems.AddRange(items1.Select(x => new CounterPartRanking { Rank = 1, CounterPart = x }));
if (items2.Any())
rankedItems.AddRange(items2.Select(x => new CounterPartRanking { Rank = 2, CounterPart = x }));
if (items3.Any())
rankedItems.AddRange(items3.Select(x => new CounterPartRanking { Rank = 3, CounterPart = x }));
if (items4.Any())
rankedItems.AddRange(items4.Select(x => new CounterPartRanking { Rank = 4, CounterPart = x }));
if (items5.Any())
rankedItems.AddRange(items5.Select(x => new CounterPartRanking { Rank = 5, CounterPart = x }));
if (items6.Any())
rankedItems.AddRange(items6.Select(x => new CounterPartRanking { Rank = 6, CounterPart = x }));
if (items7.Any())
rankedItems.AddRange(items7.Select(x => new CounterPartRanking { Rank = 7, CounterPart = x }));
sw.Stop();
Debug.WriteLine("Time elapsed {0} for {1}", sw.Elapsed, pattern);
var items = rankedItems.OrderBy(x => x.Rank).Select(x => x.CounterPart);
var distinct = items.Distinct();
return distinct;
}
}
有什么建议吗? 感谢
答案 0 :(得分:0)
利用Contains(pattern)
,StartsWith(pattern)
和== pattern
越来越具体的子集这一事实会有所帮助:
即。
var items3 = source.Where(x => x.Code.Contains(pattern));
var items2 = items3.Where(x => x.Code.StartsWith(pattern));
var items1 = items2.Where(x => x.Code == pattern);
应该导致比每次检查source
整个
答案 1 :(得分:0)
看看这是否提高了性能
public static class CounterpartExtensions
{
public static IEnumerable<Counterpart> SearchWithRank(this IEnumerable<Counterpart> source, string pattern)
{
Stopwatch sw = Stopwatch.StartNew();
var rankedItems = new List<CounterPartRanking>();
foreach (Counterpart counterpart in source)
{
if ((counterpart.Code != null) && (counterpart.Code == pattern))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 1, CounterPart = counterpart });
}
else
{
if ((counterpart.Code != null) && (counterpart.Code.StartsWith(pattern)))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 2, CounterPart = counterpart });
}
else
{
if ((counterpart.Code != null) && (counterpart.Code.Contains(pattern) == pattern))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 3, CounterPart = counterpart });
}
}
}
if ((counterpart.Description != null) && (counterpart.Description.Contains(pattern) == pattern))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 4, CounterPart = counterpart });
}
if ((counterpart.Aliases != null) && (counterpart.Aliases == pattern))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 5, CounterPart = counterpart });
}
else
{
if ((counterpart.Aliases != null) && (counterpart.Aliases.StartsWith(pattern)))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 6, CounterPart = counterpart });
}
else
{
if ((counterpart.Aliases != null) && (counterpart.Aliases.Contains(pattern)))
{
rankedItems.AddRange(new CounterPartRanking { Rank = 7, CounterPart = counterpart });
}
}
}
}
sw.Stop();
Debug.WriteLine("Time elapsed {0} for {1}", sw.Elapsed, pattern);
var items = rankedItems.OrderBy(x => x.Rank).Select(x => x.CounterPart);
var distinct = items.Distinct();
return distinct;
}
}
答案 2 :(得分:0)
我喜欢这种方法:
public static IEnumerable<Counterpart> SearchWithRank(this IEnumerable<Counterpart> source, string pattern)
{
var sources = new []
{
source.Where(x => x.Code == pattern),
source.Where(x => x.Code.StartsWith(pattern)),
source.Where(x => x.Code.Contains(pattern)),
source.Where(x => x.Description.Contains(pattern)),
source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description == pattern)),
source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description.StartsWith(pattern))),
source.Where(x => x.Aliases != null && x.Aliases.Any(y => y.Description.Contains(pattern))),
};
Stopwatch sw = Stopwatch.StartNew();
var rankedItems =
sources
.SelectMany((x, n) => x.Select(y => new CounterPartRanking { Rank = n + 1, CounterPart = y }))
.ToList();
sw.Stop();
Debug.WriteLine("Time elapsed {0} for {1}", sw.Elapsed, pattern);
var items = rankedItems.OrderBy(x => x.Rank).Select(x => x.CounterPart);
var distinct = items.Distinct();
return distinct;
}
它可能不会更快,但它更简洁的代码。在我的书中,这种方式更好。