『性能』测试一下 MSSqlHelper 的性能
本文没啥技术含量,就是测试一下 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 的性能的更多相关文章
- 『性能』List 和 HashSet 查找性能比较 (任何数据量的检索 从此只用 HashSet )
结论: 总数 50000 (5万): List 检索 5W次 耗时 23秒, HashSet 检索 5W次 耗时 0.01秒. 总数 5000 (5千): List 检索 5K次 耗时 0.16秒 ...
- 『MXNet』第六弹_Gluon性能提升
一.符号式编程 1.命令式编程和符号式编程 命令式: def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = ...
- 『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程
https://www.cnblogs.com/hellcat/p/9084894.html 目录 一.符号式编程 1.命令式编程和符号式编程 2.MXNet的符号式编程 二.惰性计算 用同步函数实际 ...
- Struts2、SpringMVC、Servlet(Jsp)性能对比 测试
Struts2.SpringMVC.Servlet(Jsp)性能对比 测试 . Servlet的性能应该是最好的,可以做为参考基准,其它测试都要向它看齐,参照它. 做为一个程序员,对于各个框架的性能要 ...
- 『MXNet』专题汇总
MXNet文档 MXNet官方教程 持久化模型 框架介绍 『MXNet』第一弹_基础架构及API 『MXNet』第二弹_Gluon构建模型 『MXNet』第三弹_Gluon模型参数 『MXNet』第四 ...
- 『Nltk』常用方法
引言 在nltk的介绍文章中,前面几篇主要介绍了nltk自带的数据(书籍和语料),感觉系统学习意义不大,用到哪里看到那里就行(笑),所以这里会从一些常用功能开始,适当略过对于数据本体的介绍. 文本处理 ...
- 【转】Web性能压力测试工具之ApacheBench(ab)详解
PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个自带的,名为ab的程序,可以对Apache或其它类型的服务器进行网 ...
- [AapacheBench工具]web性能压力测试工具的应用与实践
背景:网站性能压力测试是性能调优过程中必不可少的一环.服务器负载太大而影响程序效率是很常见的事情,一个网站到底能够承受多大的用户访问量经常是我们最关心的问题.因此,只有让服务器处在高压情况下才能真正体 ...
- Web性能压力测试工具之ApacheBench(ab)详解
PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个自带的,名为ab的程序,可以对Apache或其它类型的服务器进行网 ...
随机推荐
- python pandas import 失败
今天因为数据处理的需要,安装了pandas. 我的python版本是2.7,使用的编辑器是pycharm.我现在cmd中输入了pip install pandas,然后显示安装成功,但是在使用pand ...
- 安装Redis 编译make gcc: error trying to exec 'cc1': execvp: 没有该文件或目录的错误
Linux(Redhat) make: gcc: error trying to exec 'cc1': execvp: 没有该文件或目录的错误 排查错误: 1.检查gcc.gcc-c++是否安装rp ...
- Web移动端页面 --响应式和动态REM
响应式 什么是响应式页面呢? 顾名思义响应式页面就是能做出响应的页面,它的页面效果不是定死的,会随着用户的改变而改变. 如何着手响应式有以下几个思考的方向 找一份设计图 使用Media Query 隐 ...
- IP路由及静态路由配置
IP路由及静态路由配置 qianghaohao(CodingNutter) 链接来源:http://www.cnblogs.com/codingnutter/p/5654271.html 一.IP路由 ...
- python访问mysql
1,下载mysql-connector-python-2.0.4 pythoin访问mysql需要有客户端,这个就是连接mysql的库 解压后如下图: 双击lib 以windows为例 把mysql ...
- 洛谷 P2491 解题报告
P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...
- 最近面了不少java开发,据此来说下我的感受:哪怕事先只准备1小时,成功概率也能大大提升
本人最近几年一直在做java后端方面的技术面试官,而在最近两周,又密集了面试了一些java初级和高级开发的候选人,在面试过程中,我自认为比较慎重,遇到问题回答不好的候选人,我总会再三从不同方面提问,只 ...
- redis的持久化之RDB的配置和原理
Redis优秀的性能是由于其将所有的数据都存储在内存中,同样memcached也是这样做的,内存中的数据会在服务器重启后就没有了,也就是不能保证持久化.但是为什么Redis能够脱颖而出呢,很大程度上是 ...
- 创建ndarray
Numpy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器,是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的. 创建数组最简单的方法就 ...
- android dp深度解析(转)
我转载地方的连接:http://zhangkun716717-126-com.iteye.com/blog/1772696 当笔记记录一下 dip: device independent pixel ...