究竟是什么可以比反射还快实现动态调用?| Source Generators版

前言

最近在公众号上看到一篇文章《究竟是什么可以比反射还快实现动态调用?》,它使用的是Newbe.ObjectVisitor,基于C#表达式树访问一个普通class的所有属性和对应的值,可以拥有比直接使用反射快上10倍的性能。

就这一需求来说,我认为Source Generators应该会更快,因为访问代码在编译时而不是运行时就生成了。

事实也验证了确实如此:

2ab9a43b49583a63b0d2cd0b77eceb5f.png

实现

这次我们使用第三方开发的Source Generators类库来实现。

1.引用Nuget包

创建示例控制台程序,引用如下Nuget包:

AOPMethodsCommon
AOPMethodsGenerator

2.设置Attribute

在需要动态调用的类上声明Attribute:

[AutoMethods(template = TemplateMethod.CustomTemplateFile, CustomTemplateFileName = "template.txt")]
public class Yueluo

3.代码模板

添加template.txt,用在Source Generators生成动态调用代码的模板.

内容如下:

using System;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using System.Runtime.CompilerServices;
namespace {{NamespaceName}} {public static class {{ClassName}}Extentions{public static string ValueStringProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType  == "string" ) ~}}if(string.Compare("{{mi.Name}}",val,StringComparison.CurrentCultureIgnoreCase)==0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException("cannot find "+ val);}public static int ValueIntProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType  == "int" ) ~}}if(string.Compare("{{mi.Name}}",val,StringComparison.CurrentCultureIgnoreCase)==0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException("cannot find "+ val);}public static object ValueProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}if(string.Compare("{{mi.Name}}",val,StringComparison.CurrentCultureIgnoreCase)==0) {return obj.{{mi.Name}};}{{~ end ~}}throw new ArgumentException("cannot find "+ val);}}
}

模板使用了scriban进行解析,具体语法详见:https://github.com/scriban/scriban/blob/master/doc/language.md

ValueStringProperty方法举例来说:

public static string ValueStringProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType  == "string" ) ~}}if(string.Compare("{{mi.Name}}",val,StringComparison.CurrentCultureIgnoreCase)==0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException("cannot find "+ val);
}

遍历类的所有属性(Properties),判断当前属性返回类型(mi.ReturnType)是string,则返回对应属性名的值。

4.使用

下面是Benchmark测试代码,分别使用了Newbe.ObjectVisitorSource Generators

[Benchmark]
public string GetterString()=> ValueGetter<Yueluo, string, string>.GetGetter(_nameProperty).Invoke(_yueluo);[Benchmark]
public int GetterInt()=> ValueGetter<Yueluo, int, int>.GetGetter(_ageProperty).Invoke(_yueluo);[Benchmark]
public string GetterString2()
{ return _yueluo.ValueStringProperty("Name"); 
}[Benchmark]
public int GetterInt2()
{return  _yueluo.ValueIntProperty("Age");
}

可以看到,Source Generators生成的代码可读性更高。

结论

对于编译时可生成的功能,尽量使用Source Generators实现,可以达到更好的性能和可读性。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ofbiz中的数据模型

DelegatorDelegator是整个ofbiz中数据库访问的入口&#xff0c;具体实现是GenericDelegator类&#xff0c;在这个类中通过protected ModelReader modelReader null;protected ModelGroupReader modelGroupReader null;这两个属性变量去查找在xml文件中定义的数据模型ModelRea…

oracle 大页配置,【Oracle】Oracle如何开启大页

前言&#xff1a;在Linux中配置hugepage可以提高oracle的性能&#xff0c;减少oracle sga的页交换&#xff0c;类似于aix中的lagepage。为什么 使用大页&#xff1f;LINUX内存的默认块大小是4K如果SGA为&#xff1a;128Gselect 128* 1024* 1024/4 from dual;33554432个块(三千多…

python关联分析sklearn_Python3利用pandas,sklearn进行关联度分析以及预测的demo

做个简单的demo记录下&#xff0c;防止忘记先看原始数据&#xff1a;一共有5列&#xff1a;日期&#xff0c;金钱&#xff0c;性别&#xff0c;工作年限,年龄。我们的目的是要分析各个维度对金钱的影响。关联度分析代码&#xff1a;# -*- coding: utf-8 -*-from numpy import a…

NLB+Cluster(一)

这也算是个群集系列版吧&#xff01;首先在前面大家已经看到了利用openfiler建立仲裁磁盘&#xff0c;然后通过Linux开源软件openfiler与windows群集的结合一文看到了windows cluster群集上如何构建文件共享及DHCP服务。那么本次我们将要升级到一个较高的层次&#xff0c;来看一…

只要懂得拒绝,哪会有什么狗血感情与莫名其妙的误会

1 就凭你&#xff1f;也想握朕的手&#xff1f;2 来&#xff0c;快站好~抱好娃&#xff01;拍全家福啦&#xff01;3 自我约束有利于家庭和谐&#xff0c;嗯&#xff01;4 问题来了&#xff0c;你是夜灯党还是漆黑党&#xff1f;你点的每个赞&#xff0c;我都认真当成了喜欢

JS设置文本框只能是数字和小数点。

核心提示&#xff1a;JS判断只能是数字和小数点 只能输入字母和汉字 只能输入字母和汉字 JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入) <input οnkeyup"this.valuethis.value.replace(/\D/g,)" onafterpaste"this.valuethis.value…

如何使用 Linq 获取每个分组中的第一个元素?

咨询区 Arian&#xff1a;考虑下面的记录:Id F1 F2 F3 -------------------------------------------------1 Nima 1990 102 Nima 1990 113 Nima 2000 …

oracle unpivot 空值,sql – 处理UNPIVOT中的NULL值

这很难看,但不依赖于必须找到NULL的带外替换&#xff1a;declare pivot_task table(age int null,[a] numeric(8,2),[b] numeric(8,2),[c] numeric(8,2),[d] numeric(8,2),[e] numeric(8,2));insert into pivot_task values (18, 0.5, null, 0.6, 1.21, 1.52),(19, 7.51, 6.51,…

android笔记之在WebView中显示ProgressBar的两种方法

http://blog.csdn.net/liuzhidong123/article/details/6450334 本文基于Creative Commons Attribution 2.5 China Mainland License发布&#xff0c;欢迎转载&#xff0c;演绎或用于商业目的&#xff0c;但是必须保留本文的署名http://www.cnblogs.com/luminji&#xff08;包含…

绝对不能错过!2009~2019 高中数学联赛11年真题解析

全世界只有3.14 % 的人关注了爆炸吧知识参加过高中数学联赛的同学都知道&#xff0c;全国高中数学联赛作为中国数学会及各省、市、自治区数学会的一项经常性工作&#xff0c;是属于较高等级的数学竞赛&#xff0c;其地位远高于各省自行组织的数学竞赛。为什么这个竞赛会这么特别…

在Win7中怎样打开摄像头?

在Win7中怎样打开摄像头&#xff1f;标题所说的问题在我装了win7后也遇到了&#xff0c;当时我也只会用等下我说的第一个方法打开摄像头&#xff0c;不过幸运的是我在前些天了解到了另外一个方法&#xff0c;那么现在我先讲下这个问题出现的原因吧&#xff1a;在Win7推出后就因…

python gdb coredump_Linux段错误及GDB Coredump调试方法

最近在Linux环境下做C语言项目&#xff0c;由于是在一个原有项目基础之上进行二次开发&#xff0c;而且项目工程庞大复杂&#xff0c;出现了不少问题&#xff0c;其中遇到最多、花费时间最长的问题就是著名的“段错误”(Segmentation Fault)。借此机会系统学习了一下&#xff0…

目标行动实现

最进看了本书。感觉有几个词&#xff0c;挺好的。愿景 执行 价值。做事要先看要不要做。在做&#xff0c;做完有价值。这是个朴实的道理。要实际践行啊。复杂的事情简单做&#xff0c;简单的事情重复做。这样好了。天人和1&#xff0c;转载于:https://www.cnblogs.com/wcLT/arc…

活久见啊,WPF工资已经这么高了!

金九银十高薪季&#xff0c;WPF招聘大厂多高薪多&#xff0c;阿里影视、百度地图、华为小米、小鹏特斯拉、美的碧桂园等都在招WPF人才&#xff0c;薪资30w起步&#xff0c;真心太牛了&#xff01;为何WPF上位机自动化能异军突起&#xff1f;其实就是站在了IOT物联网的风口&…

oracle虚拟用户是什么意思,lr脚本中oracle 2tier虚拟用户相关内容

目的&#xff1a; 本文记录一些在使用oracle 2tier时了解的东西。以防止自己忘记 (一)如果选择录制脚本的话 1、vugen会生成以下这些跟其他协议不同的文件 vdf.h 作用&#xff1a;定义各种变量 print.inl 作用&#xff1a;打印表格使用的函数。录制脚本时才有用&#xff0c;写脚…

视图加载时自动执行铵钮事件

再学习一个方法&#xff0c;就是在ASP.NET MVC视图加载时&#xff0c;让jQuery自动执行一个铵钮事件。在控制器添加一个Action操作&#xff1a; 先在视图实现一个铵钮事件&#xff1a; 看看上面运行时的效果&#xff0c;当视图加载时&#xff0c;需要人为去点击铵钮&#xff0c…

硕博士的朋友圈都有哪些特点?

全世界只有3.14 % 的人关注了爆炸吧知识很多同学都会有这种感觉&#xff0c;读了硕士博士后&#xff0c;兴趣会突然间发生很大变化&#xff0c;发朋友圈也会不一样了。而真正决定人与人之间的差距的&#xff0c;其实是我们对事物的见识与内心的格局&#xff0c;见识的深浅决定人…

iphone UILabel 顶部对齐(top align)

通常UILabel如果设置了numberOfLines &#xff1d; 0&#xff0c;就会在父控件的中间显示&#xff0c;如何才能让其顶部对齐&#xff0c;通过一下的方式就能实现top align1、给myLabel标签内填充文本Label.text "文字内容;2、设置myLabel中希望的最大显示行数Label.numbe…

DataForm 中通过外面的按钮进行提交时,出错

并且有未提交的更改。调用 BeginEdit 后必须调用 EndEdit 或 CancelEdit 才能提交更改 解决方法&#xff1a; this.dataForm1.CommitEdit();转载于:https://www.cnblogs.com/Ken-Cai/archive/2012/05/29/2523954.html

python的缩进机制是其缺点之一_Python 的缩进是不是反人类的设计?

前些天&#xff0c;我写了《Python为什么使用缩进来划分代码块&#xff1f;》&#xff0c;文中详细梳理了 Python 采用缩进语法的 8 大原因。我极其喜欢这种简洁优雅的风格&#xff0c;所以对它赞美有加。然而文章发出去后&#xff0c;非常意外&#xff0c;竟收到了大量的反对意…