Dapper.net的速度很快,最近看源码,原来他orm的实现是通过编写大量IL代码实现的。
使用DynamicMethod,自己编织一个给实体赋值的方法。这种写法效率很高,接近直接对属性赋值。比使用反射赋值效率高10倍左右。
下面分别使用Emit,反射,直接赋值100000次来进行对比测试。

public static Action<T, object> EmitSetter<T>(string propertyName)
{
var type = typeof(T);
var dynamicMethod = new DynamicMethod("EmitCallable", null, new[] { type, typeof(object) }, type.Module);
var iLGenerator = dynamicMethod.GetILGenerator(); var callMethod = type.GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
var parameterInfo = callMethod.GetParameters()[];
var local = iLGenerator.DeclareLocal(parameterInfo.ParameterType, true); iLGenerator.Emit(OpCodes.Ldarg_1);
if (parameterInfo.ParameterType.IsValueType)
{
// 如果是值类型,拆箱
iLGenerator.Emit(OpCodes.Unbox_Any, parameterInfo.ParameterType);
}
else
{
// 如果是引用类型,转换
iLGenerator.Emit(OpCodes.Castclass, parameterInfo.ParameterType);
} iLGenerator.Emit(OpCodes.Stloc, local);
iLGenerator.Emit(OpCodes.Ldarg_0);
iLGenerator.Emit(OpCodes.Ldloc, local); iLGenerator.EmitCall(OpCodes.Callvirt, callMethod, null);
iLGenerator.Emit(OpCodes.Ret); return dynamicMethod.CreateDelegate(typeof(Action<T, object>)) as Action<T, object>;
}

下面是反射的写法

public static void ReflectSetter(object obj, string propertyName, object propertyValue)
{
var type = obj.GetType();
var propertyInfo = type.GetProperty(propertyName);
propertyInfo.SetValue(obj, propertyValue,null);
}

我们新建一个简单实体,添加一个属性。

public class Model
{
public string Name { get; set; }
}

下面进行测试

private void Button_Click(object sender, RoutedEventArgs e)
{
Model model = new Model();
TimeSpan ts1;
DateTime time1 = DateTime.Now; var emitSetter=EmitSetter<Model>("Name"); for (int i = ; i < ; i++)
{
emitSetter(model, "测试");
}
DateTime time2 = DateTime.Now; ts1 = time2 - time1;
Console.WriteLine("emit:"+ts1.TotalMilliseconds); DateTime t3 = DateTime.Now;
for (int i = ; i < ; i++)
{
ReflectSetter(model,"Name", "测试");
}
DateTime t4 = DateTime.Now;
ts1 = t4 - t3;
Console.WriteLine("reflect"+ts1.TotalMilliseconds); DateTime t5 = DateTime.Now;
for (int i = ; i < ; i++)
{
model.Name = "测试";
}
DateTime t6 = DateTime.Now;
ts1 = t6 - t5;
Console.WriteLine("直接赋值"+ts1.TotalMilliseconds);
}

运行结果如下图所示:

 
image.png

使用Emit执行时间大概是直接赋值的两倍,使用反射执行时间大概是直接赋值的三十多倍。Emit效率是反射的十倍以上。

使用Emit实现给实体赋值的更多相关文章

  1. asp.net DataReader DataTable 使用反射给给实体赋值

    asp.net 使用反射给给实体赋值 实体类继承此基类 using System.Reflection; using System.Data.SqlClient; using System.Data; ...

  2. c#使用emit方法DB,实体相互转换

    网上有很多ORM框架和数据库转换方法. c#由EF控制,但是大家知道的是影响效率和底层控制. 因此最近几个月一直在研究.最后产出了Hikari数据库连接池. 但是该库只是定位在连接池,无法有效进行后续 ...

  3. 【转】利用反射快速给Model实体赋值

    原文地址:http://blog.csdn.net/gxiangzi/article/details/8629064 试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有 ...

  4. EF架构~AutoMapper对象映射工具简化了实体赋值的过程

    回到目录 AutoMapper是一个.NET的对象映射工具,一般地,我们进行面向服务的开发时,都会涉及到DTO的概念,即数据传输对象,而为了减少系统的负载,一般我们不会把整个表的字段作为传输的数据,而 ...

  5. 利用反射快速给Model实体赋值

    试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...

  6. 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)

    试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...

  7. C# 同类型实体赋值

    #region 更新赋值,前者赋值给后者 public static void ShadowCopy(object a, object b) { if (a == null) return; if ( ...

  8. java两个实体公共属性赋值方法

    model1 info=new model1();info.setAge("123");info.setCode("1234");info.setName(&q ...

  9. MongoDB学习笔记~MongoDB实体中的值对象

    回到目录 注意,这里说的值对象是指在MongoDB实体类中的,并不是DDD中的值对象,不过,两者也是联系,就是它是对类的补充,自己本身没有存在的价值,而在值对象中,也是不需要有主键Id的,这与DDD也 ...

随机推荐

  1. yum安装nagois

    多少年前就装过了,今天再来用yum装一次,都忘干净了~~ 主监控机:CentOS 6.5 192.168.0.105被监控机:CentOS 6.5 192.168.0.107 主监控机设置:1.安装e ...

  2. [Python] numpy.Matrix

    import numpy as np np.matrix('1, 2; 3, 4') #1, 2 #3, 4 np.matrix([[1,2],[3,4]]) #1, 2 #3, 4

  3. 并发服务器和HTTP协议

    单进程服务器 1. 完成一个简单的TCP服务器 from socket import * serSocket = socket(AF_INET, SOCK_STREAM) # 重复使用绑定的信息 se ...

  4. django单表操作,增、删、改、查

    一.实现:增.删.改.查 1.获取所有数据显示在页面上 model.Classes.object.all(),拿到数据后,渲染给前端;前端通过for循环的方式,取出数据. 目的:通过classes(班 ...

  5. Java——复制txt文件

    将源文件复制到目标文件,同时输出源文件内容,需要提供一个源文件和目标文件路径参数(如果不存在则自动创建) public static void copyTxt(String sourceFile, S ...

  6. np的归纳总结

    1. np.sqrt(input)    # 求数的开方 import numpy as np print(np.sqrt(2)) 2. np.square(3)   # 求数的平方 import n ...

  7. 跟我学算法-吴恩达老师(超参数调试, batch归一化, softmax使用,tensorflow框架举例)

    1. 在我们学习中,调试超参数是非常重要的. 超参数的调试可以是a学习率,(β1和β2,ε)在Adam梯度下降中使用, layers层数, hidden units 隐藏层的数目, learning_ ...

  8. 跟我学算法- tensorflow 卷积神经网络训练验证码

    使用captcha.image.Image 生成随机验证码,随机生成的验证码为0到9的数字,验证码有4位数字组成,这是一个自己生成验证码,自己不断训练的模型 使用三层卷积层,三层池化层,二层全连接层来 ...

  9. ElasticSearch、Kibana 启动(含前台和后台启动、停止)(含界面浏览)

    前提: Elasticsearch-2.4.3的下载(图文详解) Elasticsearch-2.4.3的单节点安装(多种方式图文详解) Elasticsearch-2.4.3的3节点安装(多种方式图 ...

  10. __stdcall详解

    对_stdcall 的理解(上) 在C语言中,假设我们有这样的一个函数:int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用 ...