日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 究竟是什么可以比反射还快实现动态调用?| Source Generators版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近在公眾號上看到一篇文章《究竟是什么可以比反射還快實現動態調用?》,它使用的是Newbe.ObjectVisitor,基于C#表達式樹訪問一個普通class的所有屬性和對應的值,可以擁有比直接使用反射快上10倍的性能。

就這一需求來說,我認為Source Generators應該會更快,因為訪問代碼在編譯時而不是運行時就生成了。

事實也驗證了確實如此:

實現

這次我們使用第三方開發的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.ObjectVisitor和Source 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“

總結

以上是生活随笔為你收集整理的究竟是什么可以比反射还快实现动态调用?| Source Generators版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。