Ami*_*shi 10 c# linq performance database-performance dapper
我从Marc Gravell(@MarcGravell)那里读到了这个答案:https://stackoverflow.com/a/47790712/5779732
最后一行说:
作为代码的次要优化:首选AsList()到ToList()以避免创建副本.
该陈述是关于QueryMultiple()哪些回报GridReader.
在我的理解中,System.Linq提供了一种扩展方法IEnumerable.ToList().以下是从微软约ToList().
ToList(IEnumerable)方法强制立即进行查询评估并返回包含查询结果的List.您可以将此方法附加到查询中,以获取查询结果的缓存副本.
IDbConnection.Query()将永远返回IEnumerable或null.在调用代码时可以轻松完成空检查.那么有什么区别AsList呢?
如果我的理解是正确的,AsList将始终在内部调用ToList哪个将创建副本.
考虑到这一点,是AsList()不是更好ToList()用IDbConnection.Query(),它返回IEnumerable?如是; 为什么?
AsList()在这种情况下,内部是什么使它成为更好的选择?
Evk*_*Evk 11
AsList是一种自定义Dapper扩展方法.它所做的只是检查IEnumerable<T>你是否真的传递给它List<T>.如果是 - 它将它返回,只是转换为List<T>.如果不是 - 它会定期调用ToList.关键是 - ToList()总是创建一个副本,即使你传递给它的是一个列表.AsList()方法避免执行此复制,因此如果不需要此类复制,则非常有用.
在此特定方案中,您具有以下代码:
multipleresult.Read<MerchantProduct>()
Run Code Online (Sandbox Code Playgroud)
哪里multipleresult是GridReader.Read具有buffered默认情况下为true的参数.当它真实 - Read将真正返回List<T>,所以通过调用ToList你将再次复制该列表没有太多理由.
同样如此IDbConnection.Query()- 是也有buffered参数,默认情况下为true,因此它也会默认返回List<T>.
如果你喜欢使用ToList()-你可以传递buffered: false到Query()或Read()以避免产生额外的副本.
此扩展是一个自定义的简洁扩展,它在调用之前执行额外的检查ToList。 来源:
public static List<T> AsList<T>(this IEnumerable<T> source)
=> (source == null || source is List<T>) ? (List<T>)source : source.ToList();
Run Code Online (Sandbox Code Playgroud)
ToList总是创建一个新List<T>实例并用给定的项目填充它AsList检查序列是否已经是 a List<T>,然后它将直接转换它当然,这种方法可能更有效,因为铸造某些东西比创建和填充新东西要少得多。所以这是完全不同的。
这是基于意见的,但我发现这很危险。有人可能会忽略AsList并阅读ToList或只是不知道其中的区别。如果以后有人更改代码,那就很危险了。
例如,采用以下方法的IEnumerable<T>方法AsList:
public static List<T> GetResult<T>(IEnumerable<T> seq)
{
if(some condition here)
{
seq = seq.Where(some predicate here);
}
return seq.AsList()
}
Run Code Online (Sandbox Code Playgroud)
现在代码用一个列表调用这个方法:
IEnumerable<string> sequence = (gets a list from somewhere)
List<string> userList = GetResult(sequence);
Run Code Online (Sandbox Code Playgroud)
后来有人认为数组在这里更合适:
IEnumerable<string> sequence = (gets an array from somewhere)
List<string> userList = GetResult(sequence);
Run Code Online (Sandbox Code Playgroud)
直到现在这并没有真正伤害到。现在,一个新的列表已初始化并填充,因为源不是列表并且无法转换。所以它的效率较低。但如果逻辑也依赖于列表是相同的引用,那么这将不再起作用。
if(userList == seq)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
false一旦使用了数组,就会出现这种情况。于是密码就被悄无声息地破解了。
长话短说:我不喜欢这种AsList方法。您始终可以自己检查类型。
| 归档时间: |
|
| 查看次数: |
3543 次 |
| 最近记录: |