来自IDataReader的.NET对象运行缓慢
我正在尝试对大约400个业务对象的列表进行水合物化,当需要水合物化字符串时,性能会变得非常缓慢。需要超过20秒才能使400个物体水合 编辑 我们使用MySQL 5.1和dotConnect for MySQL v5.0.12作为数据提供程序 我做了一些基准测试,将其缩小到导致问题的字符串类型。我开始测量从记录2到n的时间,以忽略加载其他程序集可能占用的时间 下面的代码以0毫秒为单位显示1个对象来自IDataReader的.NET对象运行缓慢,.net,performance,string,datareader,.net,Performance,String,Datareader,我正在尝试对大约400个业务对象的列表进行水合物化,当需要水合物化字符串时,性能会变得非常缓慢。需要超过20秒才能使400个物体水合 编辑 我们使用MySQL 5.1和dotConnect for MySQL v5.0.12作为数据提供程序 我做了一些基准测试,将其缩小到导致问题的字符串类型。我开始测量从记录2到n的时间,以忽略加载其他程序集可能占用的时间 下面的代码以0毫秒为单位显示1个对象 objUserInfo.PortalID = portalId objUserInfo.IsSuper
objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = "FirstName"
这也会在0毫秒内为1个对象添加水合物
objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = "FirstName"
但是,只要我将datareader对象转换为字符串,平均需要53毫秒
objUserInfo.PortalID = portalId
objUserInfo.IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
objUserInfo.UserID = Convert.ToInt32(dr("UserID"))
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))
我还试着给两根琴弦补水,然后勒死它,它的表现不会比一根琴弦差多少?
以下仅需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"))
我知道很多人使用上述语法来水合业务对象。有没有更有效/更快的方法来实现这一点
编辑
刚刚做了另一个测试,在一个字符串上进行directcast,它会产生相同的慢速:(53毫秒,仅用于进行转换)
objUserInfo.FirstName = DirectCast("alex", String)
我还试过给2根琴弦和strangley浇水,但它的效果不如1根琴弦那么好?下面的每根琴弦平均浇水57毫秒
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"))
你是如何测量时间的?可能有一个额外的装配负载,你的53毫秒考虑到了这一点
您应该仅在第一次循环(第一次水合)之后开始测量时间。这样,任何组件加载都将在测量之前完成
我还试过给2根琴弦和strangley浇水,但它的效果不如1根琴弦那么好?下面的每根琴弦平均浇水57毫秒
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"))
你是如何测量时间的?可能有一个额外的装配负载,你的53毫秒考虑到了这一点
您应该在第一次循环(第一次循环)之后才开始测量时间。这样,任何程序集加载都将在测量之前完成。您使用的数据提供程序是什么?oracle one出现了一个棘手的问题 最有效的方法是调用dr.GetString(columnNumber)——其中的列号是通过dr.GetOrdinal(columnName)获得的(可以在读取循环开始时缓存)
但是,这不应该是真正的问题。难道不是列的大小吗?您使用什么数据提供程序?我们在oracle one上遇到了一个棘手的问题 最有效的方法是调用dr.GetString(columnNumber)——其中的列号是通过dr.GetOrdinal(columnName)获得的(可以在读取循环开始时缓存) 但是这不应该是真正的问题。难道不是列的大小吗?尝试一下: 而不是
objUserInfo.Firstname = Convert.ToString(dr("FirstName"))
使用
Convert.ToString(dr(“FirstName”))
正在执行一些丑陋的隐式和耗时的转换和/或(取消)装箱操作。)objUserInfo.Firstname = Convert.ToString(dr("FirstName"))
使用
Convert.ToString(dr(“FirstName”))
正在执行一些丑陋的隐式和耗时的转换和/或(取消)装箱操作。)是的,我只从2到n进行测量。第一个需要150毫秒。我会编辑这个问题以包含它。是的,我只从2到n进行测量。第一个需要150毫秒。我会编辑这个问题以包含它。我尝试了dr.GetString(2)。在相同的400个对象的3次迭代中,它给了我1毫秒的性能改进:(所以现在平均为52毫秒:)还有一些Convert.ToString(dr(…))吗?如果有,请替换或删除这些行。顺便问一下:您使用什么数据库和什么库来连接?不,这是行objUserInfo.FirstName=dr.GetString(3)。我编辑了这个问题以反映数据库和提供程序。它是MySQL 5.1和dotConnectOk,那么你必须依靠MySQL来优化转换。-)我希望你不要认为我吹毛求疵,但你真的消除了所有(!)转换操作并对所有(!)字段专门使用GetXXX方法吗?是的,100%确定:)。刚刚做了另一个测试,并将结果添加到问题中。我尝试了dr.GetString(2)。对相同的400个对象进行3次迭代后,它使我的性能提高了1ms:(所以现在平均为52ms:)是否还有一些Convert.ToString(dr(…)?如果是,请替换或删除这些行。顺便说一句:您使用什么数据库和什么库来连接?不,这是行objUserInfo.FirstName=dr.GetString(3)。我已对问题进行了编辑,以反映db和提供者。它是MySQL 5.1和dotConne