c# - 慢速 AsQueryable() 和 IQueryable 和 IEnumerable 的通用方法

标签 c# entity-framework linq iqueryable

我想对 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/

相关文章:

c# - 嵌套列表,我如何使用 lambda 表达式来做到这一点?

c# - 程序集以及何时不能选择强命名?

c# - 无法将类型 'System.Data.EntityState' 隐式转换为 'System.Data.Entity.EntityState' 。存在显式转换(您是否缺少转换?)

c# - Entity Framework 中带有 OR 条件的动态查询

c# - linq to sql事务

c# - SQL LINQ 选择标题和属于该标题的列表

c# - 如何与 Entity Framework Code First 建立一对一关系

c# - 当没有编码时,如何在整个项目文件中强制使用 C# 根命名空间?

c# - asp.net core获取项目根目录的方法Directory.GetCurrentDirectory() 在 Mac 上似乎无法正常工作

c# - Entity Framework 连接字符串问题