【问题标题】:Optimizing DataReader Results: what is the concequence of leaving the values as objects?优化 DataReader 结果:将值保留为对象的后果是什么?
【发布时间】:2018-03-07 08:42:45
【问题描述】:
var list = new List<object[]>();
var fieldCount = reader.FieldCount;
while(reader.Read()) {
    var array = new object[fieldCount];
    reader.GetValues(array);
    list.Add(array);
}

给定上面的简单代码sn-p。并假设要检索的值是值类型的混合。

  • 如果您之前知道每列的类型,是否有任何速度优势 手,并且可以正确调用那里的类型化方法来获取(全部)他们的 价值观?

  • 或者获取键入的值会减慢整个读取过程?

  • 将数据保留在对象数组中与将它们存储在类型化实体中时有哪些权衡?

【问题讨论】:

  • 假设您的数据库中有一个表,其中包含客户数据,并且您希望从该表中检索一些记录并对这些数据进行一些处理。为了访问客户对象的属性,您必须拥有一个客户对象列表。对象列表不适合。
  • 在大多数数据库访问中,最大的成本是延迟和通过网络传输数据。因此,在 C# 方面,您的主要关注点应该是易于理解代码。在任何地方使用object 会使代码更难推理。 github.com/StackExchange/Dapper 可能值得考虑。
  • @TimSchmelter 是的。这是微优化。我在这里有点过分杀戮。但这是一种强烈的好奇心。
  • No.2 主要通过连接池解决,许多框架甚至将它们的查询批处理在一起以最小化这种情况。甚至可以跟踪连接状态以查看未完成的查询在最终关闭之前是否仍然处于活动状态。
  • No.1 除非同时进行大量查询,否则今天不太可能成为问题之一。当然,这取决于所使用的数据库。同步查询(非常常见)最终可能会为该实例保留连接。您完成查询的时间越长,其他排队的查询等待的时间就越长。很简单。

标签: c# sqldatareader datareader


【解决方案1】:

如果您事先知道每列的类型,并且可以正确调用那里的类型化方法来获取(全部)它们的值,是否有任何速度优势?

是的。因为您的替代方法是检查适当的类型,例如:

if (obj is string)
{
 //Do string things
}
else if (obj is int)
{
 //Do int things
}

知道类型后,只需强制转换:

string t = (string) obj;

或者获取键入的值会减慢整个读取过程?

没有。事实上,你不能比转换为正确的类型更快。

将数据保留在对象数组中与将它们存储在类型化实体中时有哪些权衡?

将它们存储在对象数组中会占用更多内存,因为值类型被装箱为对象。

【讨论】:

  • 这部分是我希望听到但不确定的。由于装箱,存储为对象数组需要更多内存。但是使用 .GetInt32()、.GetString()、.GetBoolean() 等方法时是否存在拆箱开销?如果只是暂时的,我很好奇将开销推迟到连接关闭之后是否会产生任何影响。 ... 重要说明:对于这个例子,在管道的末端,这些值只会被转换一次。
  • 查看SqlDataReader 的源代码后,我想确认这是最佳答案。 GetValue 和 GetValues 最终会增加装箱开销,但是(因为它的设计方式)更具体的类型值是从存储未装箱值的特定 SqlBuffer 类中检索的。
  • 明确一点:我们谈论的是非常少量的。用于存储装箱值的更多字节与(可能)用于转换的纳秒。我总是使用类型化实体,它使代码更具可读性。
  • 是的。在可能的情况下使用类型化方法显然是合适的。对于我的数据访问库,我将字段映射到实体并将数据缓冲到对象数组(每条记录)中,然后应用转换。这是不值得实施的潜在优化之一。
猜你喜欢
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2021-01-24
  • 2019-04-10
  • 1970-01-01
相关资源
最近更新 更多