29

从0开始编写dapper核心功能、压榨性能、自己动手丰衣足食

 4 years ago
source link: https://www.tuicool.com/articles/BjIriqz
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我偶然听说sqlsugar的性能比dapper强。对此我表示怀疑(由于我一直使用的dapper存在偏见吧),于是自己测试了sqlsugar、freesql、dapper发现他们的给我的结果是

sqlsugar>dapper>freesql(这里并不是黑那个orm,毕竟不同orm功能不同,底层实现不同,适用场景不同性能当然不同)。这让我很吃惊,dapper(号称orm king)一个执行sql的映射器,比不了基于linq语法的sqlsugar。同时也让我感到高兴,我高兴的是:orm的性能肯定还有提升的空间。

于是我便开始研究它们并着手编写。最终以一千行左右的代码量实现了dapper的基本映射功能,性能真正意义接近ado.net

对比于dapper的底层存在拆装箱操作(我的没有,请看IL),强制类型转换,dapper内置各种缓存(缓存就要考虑并发安全,就要用lock),许多功能并不是我们所需要的,一些功能又是我们迫切需要的,dapper有些定制化功能我们要查阅很多资料才能实现。浪费我们宝贵的时间,dapper对匿名类型支持并不好,这阻碍的我的另一个框架dapper.common(dapper的linq实现方案,将来要移植到sqlcommon),我让作者改一下,支持一下,作者认为linq映射也不是dapper所需要的功能,不予支持。

自己动手丰衣足食,那么我们完全可以自己编写一套。

性能测试

V7J3Y33.png!web

fa6NfaJ.png!web

下面进行简要实现:

完整源码地址:https://github.com/1448376744/SqlCommon

nuget也发布了v1.0.0

1.我们要如何实现?我们要实现的第一个问题是DataReader对象转实体类,用反射肯定不行。我们需要用IL来动态创建下面的函数

jUfI3q6.png!web

我们可以创建这样的函数,通过IL来动态创建,大致的过程

创建实体类型->判断实体类型中的属性在reader中是否存在->如果存在则对该字段赋值

1.我们定义一个接口,,因为匹配C#字段和数据库字段名之间有一个映射规则(是否区分大小写,是否忽略下划线等等)

NbAj6vA.png!web

第一个接口要求我们传递一个类型的所有属性,和要绑定的列信息

第二个查找一个类型的转换方法(比如字段属性的bool,我们一个返回一个bool类型的转换函数)

第三个是用于处理匿名类型的,不细说了

第四个返回一个类型的构造器

我们编写一套实现

y6fqQ3i.png!web

然后实现一下 DataConvertMethod( FindConvertMethod 需要) 这里是缩减版

FVVnAjY.png!web

然后我们编写IL来创建动态函数,并使用用上面的接口作为参数

eIz6Rnm.jpg!web

rQfIbie.jpg!web

动态创建的IL绑定函数我们需要编写一个缓存策略(我们使用hash结构进行存储),一个目标类型可能生成多个绑定函数,这根据你sql返回的字段个数和顺序有关

定义hash结构的key

qyUvuuB.png!web

iQRnqqn.png!web

好了大部分工作都完成了,我们编一个sql执行器(简化版)

2qqENzV.png!web

至此我们已经完成了整个流程。

我们可以发现没有拆装箱,没有强制类型转换,

对比于使用ado.net的性能差距,由于我们的动态生成绑定函数,在下次使用的时候我们需要从hash表中去查询这个函数指针。

这便是性能的差距点,而我们首先绑定函数,下次时候的时候显示的调用你定义的绑定函数。

也就是说,你只要能优化这个缓存策略,就能无限接近手写ado.net。

原文链接:https://www.cnblogs.com/chaeyeon/p/11615863.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

b2Q7ryq.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK