C# Dapper/EF-当变量超出使用范围时,为什么会有性能提高
我使用相同的参数和存储过程运行了以下两个查询。示例A需要一分钟,而示例B不到20秒。如果我使用EF调用同一个proc,那么我只需要大约10秒(返回的记录刚刚超过50000条)。因此,为什么英孚的速度更快也令人费解 示例A:C# Dapper/EF-当变量超出使用范围时,为什么会有性能提高,c#,entity-framework,scope,dapper,using,C#,Entity Framework,Scope,Dapper,Using,我使用相同的参数和存储过程运行了以下两个查询。示例A需要一分钟,而示例B不到20秒。如果我使用EF调用同一个proc,那么我只需要大约10秒(返回的记录刚刚超过50000条)。因此,为什么英孚的速度更快也令人费解 示例A: List<resultObj> result; using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["string"
List<resultObj> result;
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["string"].ConnectionString))
{
result = conn.Query<resultObj>("spProc", param: new { /*params here*/ },
commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList();
}
列表结果;
使用(var conn=new SqlConnection(ConfigurationManager.ConnectionStrings[“string”].ConnectionString))
{
result=conn.Query(“spProc”,param:new{/*params here*/},
commandType:commandType.StoredProcess,commandTimeout:300).ToList();
}
例B:
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["string"].ConnectionString))
{
var result = conn.Query<resultObj>("spProc", param: new { /*params here*/ },
commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList();
}
使用(var conn=new SqlConnection(ConfigurationManager.ConnectionStrings[“string”].ConnectionString))
{
var result=conn.Query(“spProc”,param:new{/*params here*/},
commandType:commandType.StoredProcess,commandTimeout:300).ToList();
}
为什么将结果变量移出using的作用域会导致性能的大幅提高?您发布的两段代码在编译时将生成几乎相同的IL代码。唯一的区别是使用哪些寄存器来表示哪个变量,这不会对程序的运行方式产生任何影响
您看到的结果是此代码外部因素的结果。有很多因素会影响性能,在您的案例中,不可能确定是什么导致了问题。也许自从您第一次运行代码以来,数据库重新考虑了它的索引计划。可能您更改了对数据库连接产生意外影响的其他代码。也许远程系统在那里承受了一段时间更重的负载。但是我有信心地说,区别并不是来自您在这里提供的代码更改。没有理由这样做。在这种情况下,我怀疑任何差异都是由于数据库服务器瓶颈造成的——可能是您第一次有效地将数据预充到内存中(速度慢的一次,数据必须进入磁盘)——或者是服务器争用或网络吞吐量问题。您在这两个示例中描述的内容只能由底层数据源引起,而不是变量声明位置之间的差异 请注意:
AsList()
比ToList()
更可取,但这也只会为您节省一点点时间(可能不到一毫秒)
分析时,您应该:
- 在未连接IDE的发布模式下工作
- 首先执行JIT并初始化所有外部源,通常在开始计时之前至少执行一次
- 多次测量每件事(在快速操作的情况下,进行数千次以获得平均值是很常见的-如果每次迭代需要30秒,显然不太适用)
- 提前强制GC等,使任何额外的GC仅是被测试对象的故障
- 尽量避免在测试机器/服务器/网络上竞争
结果
超出使用范围。性能增益是偶然的。如果可以,请尝试隔离导致性能增量的差异。我的猜测是,它与可变位置无关。更可能的是,这与您在第一次运行中遇到的某种首次初始化惩罚有关。(您可以尝试再次运行原始版本,看看是否得到相同的结果)。