Eri*_*ard 1 c# performance dictionary
我需要维护一个唯一键控的数据库对象的缓存(按整数).查询提供了一个IEnumerable<MyEntity>(MyEntity使用int主键)实例和结果,我想Dictionary<int, MyEntity>尽可能快地初始化一个实例,因为这个查询可以返回几十万行.
初始化一个实例的最高效的方法Dictionary<int, MyEntity>是IEnumerable<MyEntity>什么?
简而言之,我想知道是否有更高效的方法来执行此操作:
IEnumerable<MyEntity> entities = DoSomeQuery();
var cache = new Dictionary<int, MyEntity>();
foreach (var entity in entities)
cache.Add(entity.Id, entity);
//or...
cache = entities.ToDictionary(e => e.Id);
Run Code Online (Sandbox Code Playgroud)
当然,查询具有最大的潜在性能影响,但重要的是,无论我在哪个用例中,我都要花几毫秒.
编辑:
值得注意的是,.ToDictionary<TKey, TElement> 字面意思是像第一个例子一样运行一个foreach循环,因此可以假设如果不是稍微差一点,则perf将完全相同.也许这就是我的答案.
你的速度和你一样快.
如果您可以快速确定要添加的元素数量,那么将其作为Dictionary构造函数的容量传递将通过阻止内部调整大小操作(.NET Core版本的ToDictionary()那样做,其他版本不会).
如果密钥相对紧密,那么您可以从范围而不是计数中获益.例如,如果你有Ids,{5, 6, 7, 9, 10, 11}那么将大小设置为7(如果缺少8那里你将拥有的值的数量)而不是6 是有益的.(实际上,它在这里没有任何区别,因为效果只会发挥作用比这更大的集合).其效果是相当小的,所以不值得做,如果你将要浪费大量的内存(例如,它的defintely不值得存储{8, 307}在300容量词典!好处来自于提高的关键是如何经常被散列到在内部大小(因此内部散列减少)小于完成全部添加时将会与另一个元素冲突的东西.
如果它们紧密包装但您无法预测大小,那么将它们按顺序存储是有好处的,因为随着内部存储的增长,通常情况下字典希望存储具有未使用的简化哈希值的内容码.好处虽然会比在内存中的排序的成本较小(这将需要反正找到的元素个数,任何明示或内OrderBy操作),所以如果有获得该限令为你做了廉价的方式,它只是帮助.(例如,一些web服务需要一些类型的排序标准的给予,所以你不妨给ID作为标准.晴这将不适用).
这些要点,特别是最后两点,虽然微不足道,但可能无法衡量任何可衡量的因素.即使第一个小于获得计数的成本,如果它还没有在具有廉价Count或Length操作的来源中.
在foreach本身或许可以通过索引替换(如适用),但有时也被认为是糟糕的改善.它也往往做得更好一些具体类型的源(即foreach在T[]阵列拍foreach上List<T>拍foreach的IEnumerable<T>),但是这意味着暴露层之间实现的细节,是很不值得,特别是由于许多集合类型没有任何好处,通过这一点.
| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |