CYQ.Data 轻量数据层之路 MDataTable 绑定性能优化之章(十一)

昨天jyk进群后,用Microsoft Application Center Test 对CYQ.Data 框架进行进行了一下压力测试

然后截了几张图上来,只有纯图如下:

1:使用了框架:sql 2000的分页存储过程[临时表分的页]:

2:把存储过程直接换成select语句:

3:他的框架测试结果:

4:这是测试结果了。

以下是说明:

1、DataTable :714次/秒
2、MDataTable:559 次/秒 (简单存储过程)
3、MDataTable:500 次/秒 (完整存储过程)

 

 

简单的说就是自定义的MDataTable性能不够理想,比DataTable还差,那还自定义干什么?直接使用DataTable不就了事了?

 

当然了,我当时的第一想法,MDataTable是不应该比DataTable慢的,算下体积,关联的类,都比DataTable简化这么多,怎么可能比DataTable性能差呢?

还记得我在发布:CYQ.Data 轻量数据层之路 自定义MDataTable绑定续章(七) 时,在最下面的留言中,有一个测试

示例1:测试代码如下:

测试示例1

 

 

得出的结果是:

1:MDataTable:156250
2: DataTable:1562500
结论:自定义的MDataTable比DataTable速度快10倍。

 

 

不过就在回头间,我想到了,速度慢的原因可能在其实现的绑定机制上。

于是,我在上面的测试代码中,从界面拖了两个控件,分别为之绑定控件测试:

示例2:测试代码,看两句加红标注:

测试示例2

 

 

得出的结果是:

1:MDataTable:17968750
2:DataTable: 10312500
结论:自定义的MDataTable在绑定时比DataTable慢了0.7倍左右。

 

虽然得之绑定时比DataTable慢,但具体慢的原因,还是得找出来的。

 

原因分析一:数据查询速度

第一步测试一下:返回一个MDataTable是不是比返回一个DataTable慢。

同时也怀疑是不是从SqlDataReader隐藏转换到MDataTable时,造成的性能差。

于是把框架简单修改一下,开放了SQLHelper,开放返回DataTable的方法,接着产生了以下的测试代码:

示例3:

测试示例3

 

 

测试结果:

1:MDataTable:1875000
2: DataTable:2656250
结论:直接回返自定义的MDataTable比DataTable 快0.N倍。

 

 

从以上结果看出,无论在实例化,还是在查询速度上,自定义的MDataTable都是优于DataTable的。可是结果在绑定时反而变慢了,于是继续分析。

 

原因分析二:绑定机制

第一步,从实现绑定机制上走,首先自定义的MDataTable走的绑定机制源自DataReader方式,和DataTable不一样,于是产生第一个想法:

用源生的SqlDataReader绑定和DataTable绑定比较,测试代码:

示例4:

测试示例4

 

 

测试结果:

1:     DataTable:10156250
2: SqlDataReader:8437500
结论是:用SqlDataReader绑定比DataTable绑定快一些。

 

 

于是,最后得出结论是:还真是我绑定代码写的有问题,导致性能比DataTable差了一点

 

三:代码优化之章

既然代码写的不够好,就得优化了。于是接着研究DataReader的绑定接口的实现,发现有这么一些返回代码:


    public override short GetInt16(int i)
    {
        this.ReadColumn(i);
        return this._data[i].Int16;
    }
    public override int GetInt32(int i)
    {
        this.ReadColumn(i);
        return this._data[i].Int32;
    }
    public override long GetInt64(int i)
    {
        this.ReadColumn(i);
        return this._data[i].Int64;
    }

瞬间给了我一些启发,那就是模拟相似的实现方式了:

新建了一个类CellValueType:

并增加所有类型属性,一开始是prop的一个一个敲,累死人了。


internal class CellValueType
{
        public int Int;
        public string String;
        public bool Bool;
        public byte Byte;
        public char Char;
        public long Long;
        public DateTime DateTime;
        public decimal Decimal;
        public double Double;
        public float Float;
        public Type Type;
        public Guid Guid;
        public Int16 Int16;
        public Int32 Int32;
        public Int64 Int64;
        public short Short;
}

 

接着增加方法,为属性设置值:手动敲这些代码,你说累不累人。

 

Set 方法

 

 

接着在单元格类里增加该类,并在为单元格值赋值时调用此方法:


public class MDataCell
{
        //...能省就省...
        internal CellValueType _CellValueType;
       //...能省就省...

        #region 初始化
        private void Init(CellStruct dataStruct, object value)
        {
            _CellValueType = new CellValueType();
           //...能省就省...
        }
      //...能省就省...
        public object Value
        {
            get
            {

                return _CellValue.Value;
            }
            set
            {
                //...能省就省...
                _CellValueType.Set(value);
            }
         }
}

 

一切就绪,于是回到MDataTable实现接口的实现之处,写下和DataReader相似的代码:


        public float GetFloat(int i)
        {
            return _Mdr[_Ptr][i]._CellValueType.Float;
        }
        public Guid GetGuid(int i)
        {
            return _Mdr[_Ptr][i]._CellValueType.Guid;
        }
        public short GetInt16(int i)
        {
            return _Mdr[_Ptr][i]._CellValueType.Short;
        }

 

改完之后,马上测试结果:

用的上面的示例2:

测试结果:

1: MDataTable:8906250
2: DataTable:11093750
结论:MDataTable在绑定时性能终于上去了,超越DataTable了

 

接着又用示例1:

测试结果:

1:MDataTable:312500
2:DataTable:1718750 
结论是:原来比DataTable快10倍的差距,纯减到5倍多一点。

 

 

按理就这么算了,绑定快一点,实例化时不要那么快,也是可以接受的。

不过,还是要抓个问底,究竟是哪句代码影响了性能。

于是继续研究,采取代码注释,步步换回原来的代码测试,终于把性能杀手抓出来了:


        public string GetDataTypeName(int i)
        {
            return DataType.GetDbType(_Mdr[_Ptr][i]._CellStruct.SqlType.ToString()).ToString();
        }
        public Type GetFieldType(int i)
        {
            return Type.GetType("System." + GetDataTypeName(i));
        }

 

就是这两个家伙了,上面那个家伙还行,下面那个家伙就大大的不行了,Type.GetType方法,大伙自己拈着点用了。

 

既然抓到了真胸,那我原来的模仿存在的意义好像就不是那么明显了,只要能优化这里,那些模仿可以去掉了,同时又可以恢复原来10倍的性能差距。

当然了,同时我发现通过Value.GetType是有问题的,如果绑定的值是Null,虽然可以判断了事,不过每次对Value取值也不太稳。

于是新生方法又产生了:

为单元结构添加多一个属性,换掉整个CellValueType类。

在构造头部结构时,完成对Type的初始设置,如下:


  /// <summary>
    /// 单元结构属性
    /// </summary>
    public class CellStruct
    {
       //...能省则省...
        internal Type ValueType;
        #region 构造函数
        public CellStruct(string columnName, System.Data.SqlDbType sqlType, bool isReadOnly, bool isCanNull, int maxSize, ParameterDirection paraDirection)
        {
            //...能省则省...
            ValueType = DataType.GetType(sqlType);
        }
        #endregion
    }

 

同时DataType增加一内部方法用于从SqlType转到Type:[又是手动敲的,累死人罗]

GetType 方法

 

OK,至此,相关的返回取结构体的Type属性就行了,最后看测试结果:

示例1测试结果:

1:MDataTable:156250
2:DataTable: 1718750 
结论:10倍的差距速度回来了。

 

 

对示例2测试结果:

1:MDataTable:8750000
2:DataTable:11093750 
结论:速度上仍超越了DataTable,虽然没超越多少。不过比起之前慢了0.7倍左右到现在反超回来,是一大提升了。

 

 

 

最后结案陈词:

 

继续欢迎光大群众对本框架的使用与测试,本框架将与时俱进,尽情做到让使用者放心,省心。
欢迎留言讨论。

 

 

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2010/09/01/1814901.html

时间: 2024-11-02 01:44:02

CYQ.Data 轻量数据层之路 MDataTable 绑定性能优化之章(十一)的相关文章

CYQ.Data 轻量数据层之路 bug反馈、优化建议、最新框架下载

重要说明: 所有相关的版本及下载,均转移并发布于秋色园QBlog的CYQ.Data专题博客中:http://www.cyqdata.com/cyqdata   欢迎大伙在使用过程若遇bug可及时反馈,如果有好的建议,请留言!!!   相关开源进群讨论:详见:CYQ.Data 轻量数据层之路 框架开源 所有信息汇总一览:详见:CYQ.Data 轻量数据层之路 框架开源系列 索引    V1.3版本[华丽的开始] 框架下载:V1.3 版本 点击下载 源码下载:V1.3 源码 点击下载   V1.4版

CYQ.Data 轻量数据层之路 强势V1.5 问世 支持winform下使用(十七)

继V1.4版本已过N天,同时V1.4版本也已开源,见:CYQ.Data 轻量数据层之路 优雅V1.4版本 框架开源   由于网友强烈反映需要在winform下开发,因此本次版本升级主要是增加对winform的支持,力求让大伙相对满意: 对于:bug反馈.优化建议.及最新框架版本下载见:CYQ.Data 轻量数据层之路 bug反馈/优化建议/框架下载   附言:如果对本框架有兴趣,请激昂纠纠的.热情点下推荐~   升级说明: 本次更新修正两个小bug: 1:生成sql2000的枚举语句 2:MDa

CYQ.Data 轻量数据层之路 抢先体验版本功能说明演示 (二十九)

本系列所有文章索引:CYQ.Data 轻量数据层之路 框架开源系列 索引 本系列所有相关下载:CYQ.Data 轻量数据层之路 bug反馈.优化建议.最新框架下载 前言:   一直都是发布版本才写文章,这次为抢先体验版本[V2.5]做一下简单的功能介绍   以下进行功能更新说明[相比V2.0版本]: 1:修正DebugInfo属性在异常发生时无法取得操作语句的问题 2:MAction增加Bind方法可以轻松绑定DropDownList等控件 3:MDataTable增加ToList<T>泛型方

CYQ.Data 轻量数据层之路 使用篇二曲 MAction 数据查询(十三)

上一篇:CYQ.Data 轻量数据层之路 使用篇一曲 裸身走天涯(十二)   前言说明: 本篇继续上一篇内容,本节介绍所有相关查询的使用. 主要内容提要:1:单行数据操作 Fill 操作 GetCount操作.2:多行数据操作 Select 操作3:列表绑定控件操作 配合分页控件4:多表查询及绑定 视图及自定义SQL     单行数据操作   一:Fill 填充方法,单行查询 方法原形:public bool Fill(object where) 示例1:直传ID MAction action 

CYQ.Data 轻量数据层之路 使用篇一曲 裸身走天涯(十二)

其实本来是不想写使用帮助的,因为在以下的文章中,都有大量的示例存在:   CYQ.Data 轻量数据层之路 应用示例一 留言版(四) CYQ.Data 轻量数据层之路 华丽升级 V1.3出世(五) CYQ.Data 轻量数据层之路 应用示例二 在线聊天(六) CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)   不过很多人还是很懒啊,一进群就用问怎么用. 发个文章路径让其看吧,又说太麻烦,使用复杂,于是想了想,还是写写使用教程,让这部分懒人速成一下.   当前最新版本

CYQ.Data 轻量数据层之路 V2.0 震撼惊世 支持多数据库/内置Aop(二十五)

所有文章索引:CYQ.Data 轻量数据层之路 框架开源系列 索引   前言: 从V1.5发布到现在时隔20天了,终于发布2.0版本了,2.0系列版本由于引入多数据库支持,内部结构改动较大. 但是外面调用方式仍保持一致向下兼容,因此若从原来V1.N版本升级到2.N版本,只需要轻轻更换CYQ.Data.DLL即可,界面代码不需要改变.   疑问? 最近26号才刚发布了V1.5.5,怎么才3天又发布了2.0版本?就这么点时间改动就很大,那不是很不稳定? 解疑: V1.5.5版本是拿V1.5版本的源码

CYQ.Data 轻量数据层之路 应用示例三 Aop切入留言系统--操作日志(二十七)

前言: 在8月份时,那时曾用CYQ.Data 1.2版本演示过一个完整的示例,留言版:详见:CYQ.Data 轻量数据层之路 应用示例一 留言版(四) 本篇将使用2.N系列版本,在不改动原来留言版系统一行代码的情况下,实现其数据库操作日志功能. 最新版本下载见:CYQ.Data 轻量数据层之路 bug反馈.优化建议.最新框架下载     正文步骤:   一:建表 1:增加一个日志操作表[ActionLogs],这个少不了,表结构如下: 2:创建表的数据库脚本如下: 创建ActionLogs表  

CYQ.Data 轻量数据层之路 V3.0版本发布-Xml绝对杀手(三十二)

前言: 继正式发布V2.0到现在,已30来天了,一直静悄悄的都没发布什么版本 中间仅有插播了一下:CYQ.Data 轻量数据层之路 V2.5 抢先体验版本功能说明演示 (二十九)   只因最近花了很多时间在重构一个以前的博客,目前已完成其基础功能,不日将发布相关文章. 提前预览网址:http://www.cyqdata.com/     本次版本升级内容大体说明: 1:Access应用调整2:修正对:uniqueidentifier.ntext.text.Image等几个类型的应用.3:扩展缓存

CYQ.Data 轻量数据层之路 最后开源版本V1.5.5发布[V1.4源码对外下载] (二十三)

前言: 继V1.5版本已过半个月了,这期间,不断的补充相关的使用教程与视频教程,同时也在不断的改进框架,这一切的努力都有迹可寻. 详见:CYQ.Data 轻量数据层之路 框架开源系列 索引   关于最后开源版本说明: V1.5.N 版本仍为开源版本,只是不会再增加功能,升级只为修正bug. V1.5 以上版本将仍继续发布,但不再开源.   简要升级说明: 本版本主要修正框架对于Sql 2000数据库的下应用. 同时MDataTable增加对列的删除函数.   升级记录如下: 1:修正sql 20