本文没啥技术含量,就是测试一下 MSSqlHelper 在 使用反射、不使用反射 的性能对比。

之后,不要问为什么不用 ORM 这类的东西 —— 会有另外的文章 介绍 自己这些年 自己的ORM 升级历史。

背景:

我自己有一个 MSSqlHelper, 这个 辅助类  是最基本的一个 数据库操作类。

Query 查询集合时,可以指定  reader => 对象  的委托 —— 如果不指定,则 MSSqlHelper 会自动通过反射赋值。

        static void Main(string[] args)
{
Test0();
Test1(); Test0();
Test1(); Console.ReadKey();
} public static void Test0()
{
string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
DateTime time0 = DateTime.Now;
List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK");
DateTime time1 = DateTime.Now;
Console.WriteLine("Test0 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
} public static void Test1()
{
string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
DateTime time0 = DateTime.Now;
List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK", null, reader =>
{
TS_SDK item = new TS_SDK();
item.FId = (Int64)reader["FId"];
item.FNumber = (string)reader["FNumber"];
item.FEnum = (string)reader["FEnum"];
item.FName = (string)reader["FName"];
item.FSDKName = (string)reader["FSDKName"];
item.FFullName = (string)reader["FFullName"];
item.FType = (string)reader["FType"];
item.FVisit = (string)reader["FVisit"];
item.FInheritFrom = (string)reader["FInheritFrom"];
item.FJoinBaseType = (string)reader["FJoinBaseType"];
item.FJoinChildType = (string)reader["FJoinChildType"];
item.FIsStatic = (Boolean)reader["FIsStatic"];
item.FIsOverride = (Boolean)reader["FIsOverride"];
item.FIsVirtual = (Boolean)reader["FIsVirtual"];
item.FIsAbstract = (Boolean)reader["FIsAbstract"];
item.FIsInherit = (Boolean)reader["FIsInherit"];
item.FIsNetFx = (Boolean)reader["FIsNetFx"];
item.FOutUrl = (string)reader["FOutUrl"];
item.FSummary = (string)reader["FSummary"];
item.FRtSummary = (string)reader["FRtSummary"];
item.FCSCode = (string)reader["FCSCode"];
item.FVBCode = (string)reader["FVBCode"];
item.FCPPCode = (string)reader["FCPPCode"];
item.FFSCode = (string)reader["FFSCode"];
item.FAssembly = (string)reader["FAssembly"];
item.FVersion = (string)reader["FVersion"];
item.FNameSpace = (string)reader["FNameSpace"];
item.FParentId = (Int64)reader["FParentId"];
item.FParentNumber = (string)reader["FParentNumber"];
item.FDemo = (string)reader["FDemo"];
item.FInfo = (string)reader["FInfo"];
return item;
});
DateTime time1 = DateTime.Now;
Console.WriteLine("Test1 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
}

  

运行结果:

读取了全表 7W行记录。

—— 很明显:没有指定 reader 读取的委托、使用内置的反射代码 足足慢了 3秒。

—— 当然,MSSqlHelper 内置的委托 进行了稳定性控制,使用了 这类代码:

item.FId = Tools.ToLong(reader["FId"]);
item.FName = Tools.ToString("FName");

这类转换函数,性能肯定没有 下面的代码 性能快:

item.FId = (Int64)reader["FId"];
item.FName = (string)reader["FName"];

我为什么死活坚持 Tools 提供的 类型强转?

> 因为稳定

> 转换范围广 : 兼容下面这类 变态数据库数据

//这是 浏览器的 时间格式,以下代码 能得到 2017-03-20 02:46:06 000
DateTime timeA = Tools.ToDateTime("Mon Mar 20 2017 02:46:06 GMT+0800 (中国标准时间)"); //以下代码 能得到 2017-03-19 01:43:15 000
DateTime timeA = Tools.ToDateTime("2017年3月19日 01时43分15秒");

  

我们再使用 Tools 的类型强转函数 试一试,看一下 Tools 的类型转换会浪费多少性能

        public static void Test2()
{
string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
DateTime time0 = DateTime.Now;
List<TS_SDK> list = MSSqlHelper.Query<TS_SDK>(connString, "SELECT * FROM dbo.TS_SDK", null, reader =>
{
TS_SDK item = new TS_SDK(); //这次的 reader 委托,
//类型转换 使用的 Tools.ToLong() Tools.ToLong() 这类函数
//为什么不直接用 (string)reader["FName"] 这类直接转换 ? —— 为了稳定性、我宁愿牺牲性能 item.FId = Tools.ToLong(reader["FId"]);
item.FNumber = Tools.ToString(reader["FNumber"]);
item.FEnum = Tools.ToString(reader["FEnum"]);
item.FName = Tools.ToString(reader["FName"]);
item.FSDKName = Tools.ToString(reader["FSDKName"]);
item.FFullName = Tools.ToString(reader["FFullName"]);
item.FType = Tools.ToString(reader["FType"]);
item.FVisit = Tools.ToString(reader["FVisit"]);
item.FInheritFrom = Tools.ToString(reader["FInheritFrom"]);
item.FJoinBaseType = Tools.ToString(reader["FJoinBaseType"]);
item.FJoinChildType = Tools.ToString(reader["FJoinChildType"]);
item.FIsStatic = Tools.ToBoolean(reader["FIsStatic"]);
item.FIsOverride = Tools.ToBoolean(reader["FIsOverride"]);
item.FIsVirtual = Tools.ToBoolean(reader["FIsVirtual"]);
item.FIsAbstract = Tools.ToBoolean(reader["FIsAbstract"]);
item.FIsInherit = Tools.ToBoolean(reader["FIsInherit"]);
item.FIsNetFx = Tools.ToBoolean(reader["FIsNetFx"]);
item.FOutUrl = Tools.ToString(reader["FOutUrl"]);
item.FSummary = Tools.ToString(reader["FSummary"]);
item.FRtSummary = Tools.ToString(reader["FRtSummary"]);
item.FCSCode = Tools.ToString(reader["FCSCode"]);
item.FVBCode = Tools.ToString(reader["FVBCode"]);
item.FCPPCode = Tools.ToString(reader["FCPPCode"]);
item.FFSCode = Tools.ToString(reader["FFSCode"]);
item.FAssembly = Tools.ToString(reader["FAssembly"]);
item.FVersion = Tools.ToString(reader["FVersion"]);
item.FNameSpace = Tools.ToString(reader["FNameSpace"]);
item.FParentId = Tools.ToLong(reader["FParentId"]);
item.FParentNumber = Tools.ToString(reader["FParentNumber"]);
item.FDemo = Tools.ToString(reader["FDemo"]);
item.FInfo = Tools.ToString(reader["FInfo"]);
return item;
});
DateTime time1 = DateTime.Now;
Console.WriteLine("Test2 | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
}

  

再测试一下:

—— 近期想把自己的底层辅助类 再优化一下,所以把代码翻出来,折腾一下 ~

----------------------------------------------------------------------------------------------------------------------------------------

刚刚修改了一下 反射的代码,启用了 Emit 高速反射

性能果然得到了 明显提升,性能仅损失 15 ~20%  —— 我已经知足了。

Ps. 目前的 Emit反射 使用的通用代码(内外一个辅助类) —— 如果针对性的写 Emit 代码,性能还能再次提升,但我懒得写。

----------------------------------------------------------------------------------------------------------------------------------------

增加了一个 最原生写法 —— 也就是 性能极限

        public static void TestSouce()
{
string connString = "Data Source=localhost;Initial Catalog=InkFxBlog;User Id=sa; Pwd=123.com;";
DateTime time0 = DateTime.Now; List<TS_SDK> list =new List<TS_SDK>();
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM dbo.TS_SDK";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
TS_SDK item = new TS_SDK();
item.FId = (Int64)reader["FId"];
item.FNumber = (string)reader["FNumber"];
item.FEnum = (string)reader["FEnum"];
item.FName = (string)reader["FName"];
item.FSDKName = (string)reader["FSDKName"];
item.FFullName = (string)reader["FFullName"];
item.FType = (string)reader["FType"];
item.FVisit = (string)reader["FVisit"];
item.FInheritFrom = (string)reader["FInheritFrom"];
item.FJoinBaseType = (string)reader["FJoinBaseType"];
item.FJoinChildType = (string)reader["FJoinChildType"];
item.FIsStatic = (Boolean)reader["FIsStatic"];
item.FIsOverride = (Boolean)reader["FIsOverride"];
item.FIsVirtual = (Boolean)reader["FIsVirtual"];
item.FIsAbstract = (Boolean)reader["FIsAbstract"];
item.FIsInherit = (Boolean)reader["FIsInherit"];
item.FIsNetFx = (Boolean)reader["FIsNetFx"];
item.FOutUrl = (string)reader["FOutUrl"];
item.FSummary = (string)reader["FSummary"];
item.FRtSummary = (string)reader["FRtSummary"];
item.FCSCode = (string)reader["FCSCode"];
item.FVBCode = (string)reader["FVBCode"];
item.FCPPCode = (string)reader["FCPPCode"];
item.FFSCode = (string)reader["FFSCode"];
item.FAssembly = (string)reader["FAssembly"];
item.FVersion = (string)reader["FVersion"];
item.FNameSpace = (string)reader["FNameSpace"];
item.FParentId = (Int64)reader["FParentId"];
item.FParentNumber = (string)reader["FParentNumber"];
item.FDemo = (string)reader["FDemo"];
item.FInfo = (string)reader["FInfo"];
list.Add(item);
}
}
}
} DateTime time1 = DateTime.Now;
Console.WriteLine("TestSouce | " + list.Count + " | " + (time1 - time0).TotalSeconds + "秒");
}

  

----------------------------------------------------------------------------------------------------------------------------------------

彻底完成,性能已经到达极限

PS. 笔误: Emit高速反射

『性能』测试一下 MSSqlHelper 的性能的更多相关文章

  1. 『性能』List 和 HashSet 查找性能比较 (任何数据量的检索 从此只用 HashSet )

    结论: 总数 50000 (5万): List 检索 5W次 耗时 23秒, HashSet 检索 5W次 耗时 0.01秒. 总数 5000   (5千): List 检索 5K次 耗时 0.16秒 ...

  2. 『MXNet』第六弹_Gluon性能提升

    一.符号式编程 1.命令式编程和符号式编程 命令式: def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = ...

  3. 『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程

    https://www.cnblogs.com/hellcat/p/9084894.html 目录 一.符号式编程 1.命令式编程和符号式编程 2.MXNet的符号式编程 二.惰性计算 用同步函数实际 ...

  4. Struts2、SpringMVC、Servlet(Jsp)性能对比 测试

    Struts2.SpringMVC.Servlet(Jsp)性能对比 测试 . Servlet的性能应该是最好的,可以做为参考基准,其它测试都要向它看齐,参照它. 做为一个程序员,对于各个框架的性能要 ...

  5. 『MXNet』专题汇总

    MXNet文档 MXNet官方教程 持久化模型 框架介绍 『MXNet』第一弹_基础架构及API 『MXNet』第二弹_Gluon构建模型 『MXNet』第三弹_Gluon模型参数 『MXNet』第四 ...

  6. 『Nltk』常用方法

    引言 在nltk的介绍文章中,前面几篇主要介绍了nltk自带的数据(书籍和语料),感觉系统学习意义不大,用到哪里看到那里就行(笑),所以这里会从一些常用功能开始,适当略过对于数据本体的介绍. 文本处理 ...

  7. 【转】Web性能压力测试工具之ApacheBench(ab)详解

    PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个自带的,名为ab的程序,可以对Apache或其它类型的服务器进行网 ...

  8. [AapacheBench工具]web性能压力测试工具的应用与实践

    背景:网站性能压力测试是性能调优过程中必不可少的一环.服务器负载太大而影响程序效率是很常见的事情,一个网站到底能够承受多大的用户访问量经常是我们最关心的问题.因此,只有让服务器处在高压情况下才能真正体 ...

  9. Web性能压力测试工具之ApacheBench(ab)详解

    PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个自带的,名为ab的程序,可以对Apache或其它类型的服务器进行网 ...

随机推荐

  1. 寻找DevExpress破解经历之旅

    众所周知DevExpress是收费的,但是破解版的也不少,近期公司需要做发票套打的功能让我找个打印工具,我寻思着DevExpress这个软件好像挺不错的,功能强大,看了下价格方面,好吧!2W多呢,市面 ...

  2. CentOS-Minimal版本下安装telnet服务和xinetd服务

    默认在CentOS-Minimal版本下没有安装telnet和xinetd服务. 1.安装telnet [root@localhost ~]# rpm -qa | grep telnet  --检查是 ...

  3. Django入门二之模板语法

    一. 模板变量 Context传入的可以是一个str,dict,list,甚至是一个实例对象 在html中如何调用这些对象进行取值呢 1. 变量名 {{ variable }} 返回字符串,无论是st ...

  4. Struts2文件上传--多文件上传(插件uploadify)

    公司需要把以前的Struts2自带的图片上传替换掉,因为不能一个file选择多个文件,本人直接百度搜索图片插件,  貌似就它(uploadify3.2.1)在最前面,也找过很多案例, 其中有不少问题, ...

  5. java里的堆内存于栈内存的区别

    这个区别对于我们来说并不大,这是内存分配的两种方法.一般代码逻辑,简单变量,结构体都是放入栈中,而对象,以及被装箱的数据是放入堆中的.简单来说,栈就是一个很长的栈(数据结构中的栈,如果不理解可以当做是 ...

  6. java多线程及线程安全详解

    为什么要使用多线程: 单线程只能干一件事  而多线程可以同时干好多事(将任务放到线程里执行  效率高) 而所谓同时干并不是真正意义上的同时   只是(这里就叫CPU)cpu在每个线程中随机切换来执行 ...

  7. Java 面试知识点解析(五)——网络协议篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  8. sql server 死锁排查

    记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了. 现总结下查看死锁的常用二种方式: 第一种是图形化监听: sqlserver --> ...

  9. Android开发——子进程更新UI

    方式一:Handler和Message ① 实例化一个Handler并重写handlerMessage()方法 private Handler handler = newHandler() { pub ...

  10. openfire推送离线聊天信息的插件

    插件说明 在手机的聊天应用中,经常出现的一个需求就是把用户的离线消息通过推送系统推送到用户的手机上,为了实现这个功能,本人就开发了本插件,这个openfire 插件是拦截了发给openfire用户的离 ...