0

我正在尝试对约 400 个业务对象的列表进行水合,当它需要对字符串进行水合时,性能会变得非常慢。为 400 个物体补水需要超过 20 秒。

编辑

我们使用 MySQL 5.1 和 dotConnect for MySQL v5.0.12 作为数据提供者http://www.devart.com/dotconnect/mysql/

我做了一些基准测试以将其缩小到导致问题的字符串类型。我开始测量从记录 2 到 n 的时间,以忽略加载其他程序集可能占用的时间。

以下代码在 0ms 内水合 1 个对象

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))

这也可以在 0 毫秒内为 1 个对象补水

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = "FirstName"

但是,一旦我将 datareader 对象转换为字符串,平均需要 53ms

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))

我还尝试为 2 根琴弦补水并扼杀它并没有像 1 根琴弦那样吹出性能?以下仅需要平均 57ms 来水化 1 个对象

objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))
objUserInfo.LastName = Convert.ToString(dr("LastName"))

我知道很多人使用上述语法来水合业务对象。有没有更有效/更快的方法来做到这一点?

编辑 刚刚做了另一个测试,它是在一个字符串上进行直接投射,它产生相同的慢速:( 53ms 只是为了做投射。

objUserInfo.FirstName = DirectCast("alex", String)
4

3 回答 3

2

试试这个:

代替

objUserInfo.Firstname = Convert.ToString(dr("FirstName"))

采用

objUserInfo.Firstname = dr.GetString(2);
  1. 使用 GetXXX 方法并依靠 Microsoft 优化转换。(编辑:我怀疑这Convert.ToString(dr("FirstName"))是在做一些丑陋的隐式和耗时的转换和/或(取消)装箱操作。)
  2. 不要使用字符串索引器(“FirstName”)访问列,而是使用数字索引器(2)。这更快,但可读性较差。

编辑:亚历克斯发现了问题。不是选角问题!他对此的评论:

好的,我已经找到了问题!我正在使用 DotNetNuke 并填充其中一个标准对象。问题是,当我设置 FirstName 属性时,它会再次调用配置文件对象,这实际上需要很长时间!这与字符串转换或强制转换无关。

于 2009-03-30T08:27:46.993 回答
1

您使用什么数据提供者?我们在使用 oracle one 时遇到了一个丑陋的问题。

最有效的方法是调用 dr.GetString(columnNumber) - 您通过 dr.GetOrdinal(columnName) 获得的列号(您可以在读取循环的开头缓存)。

然而,这不应该是真正的问题。不能是列的大小吗?

于 2009-03-30T08:22:31.013 回答
0

我还尝试为 2 根琴弦补水并扼杀它并没有像 1 根琴弦那样吹出性能?以下仅需要平均 57ms 来水化 1 个对象

你是如何测量时间的?也许涉及到额外的程序集加载,您的 53 毫秒将其考虑在内。

您应该仅在第一个循环(第一次水合)之后开始测量时间。这样,任何装配加载都将在测量之前完成。

于 2009-03-30T08:20:19.350 回答