我想对 IQueryable 和 IEnumerable 使用一种方法:
public static IEnumerable<T> WhereEx<T>(this IEnumerable<T> query, Expression<Func<T, bool>> exp)
{
return query.AsQueryable().Where(exp);
}
public static IEnumerable<Ship> GetShipsSome(this IEnumerable<Ship> query)
{
return query.WhereEx(x => x.Id > 150);
}
使用: 使用 IQueryable:
var x = context.Set<Ships>().AsNoTracking().GetShipsSome(); //from DB
使用 IEnumerable:
var x = shipsInRam.GetShipsSome(); //from collection in ram(list)
但是如果我使用 IEnumerable
(从 ram 中的集合中获取),我的代码比 IEnumerable.Where
慢,因为 AsQueryable()
转换收藏。我如何优化我的代码?
修复:FirstOrDefault
而不是 Where
最佳答案
在阅读了您的说法后,我并不相信 - 所以我编写了一个基准测试。
var list = Enumerable.Range(1, 1000000).ToList();
for(var i = 0; i < 100; i++)
{
var warmupA = list.WhereEx(a => a > 500000).ToList();
var warmupB = list.Where(a => a > 500000).ToList();;
var warmupC = list.WhereExCompile(a => a > 500000).ToList();;
}
var sw = new Stopwatch();
sw.Start();
for(var i = 0; i < 100; i++)
{
var wherexresult = list.WhereEx(a => a > 500000).ToList();
}
sw.Stop();
var wherextime = sw.ElapsedMilliseconds;
sw = new Stopwatch();
sw.Start();
for(var i = 0; i < 100; i++)
{
var whereresult = list.Where(a => a > 500000).ToList();
}
sw.Stop();
var whertime = sw.ElapsedMilliseconds;
sw = new Stopwatch();
sw.Start();
for(var i = 0; i < 100; i++)
{
var whereexcompileresult = list.WhereExCompile(a => a < 500000).ToList();
}
sw.Stop();
var whereexcompiletime = sw.ElapsedMilliseconds;
wherextime.Dump();
whertime.Dump();
whereexcompiletime.Dump();
public static class a {
public static IEnumerable<T> WhereExCompile<T>(this IEnumerable<T> query, Expression<Func<T, bool>> exp)
{
return query.AsQueryable().Where(exp);
}
public static IEnumerable<T> WhereEx<T>(this IEnumerable<T> query, Expression<Func<T, bool>> exp)
{
return query.Where(exp.Compile());
}
}
给出结果:
list.WhereEx(a => a > 500000) = 1320ms
list.Where(a => a > 500000) = 1572ms
list.WhereExCompile(a => a < 500000) = 1284ms
启用优化后:
list.WhereEx(a => a > 500000) = 1285ms
list.Where(a => a > 500000) = 1372ms
list.WhereExCompile(a => a < 500000) = 1263ms
差异可以忽略不计(这运行了 100,000,000 次每次,每次用时不到 1.5 秒)。如果有的话,你的方法比.Where()
更快。那么您是从哪里得知需要优化代码的?
关于c# - 慢速 AsQueryable() 和 IQueryable 和 IEnumerable 的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34266715/