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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

寻找性能更优秀的动态 Getter 和 Setter 方案

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 寻找性能更优秀的动态 Getter 和 Setter 方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

反射獲取 PropertyInfo 可以對對象的屬性值進行讀取或者寫入,但是這樣性能不好。所以,我們需要更快的方案。

方案說明

就是用表達式編譯一個Action<TObj,TValue>作為 Setter,編譯一個Func<TObj,TValue>作為 Getter。

然后把這些編譯好的委托放在一個泛型類的靜態字段中保存起來,需要使用的時候從這里面查找就可以了。

知識要點

  • 使用表達式創建委托

  • 泛型類的靜態字段是每個閉合類型獨立的,因此用于存儲和類型相關的內容非常方便

  • 實現代碼

    由于代碼中混合的使用 Switch 作為字典的陰招,所以代碼很長,此處不再羅列,僅給出鏈接:

    • -?[Github?ValueGetter](https://github.com/newbe36524/Newbe.ObjectVisitor/blob/main/src/Newbe.ObjectVisitor/Newbe.ObjectVisitor/Core/ValueGetter.cs)

    • -?[Github?ValueSetter](https://github.com/newbe36524/Newbe.ObjectVisitor/blob/main/src/Newbe.ObjectVisitor/Newbe.ObjectVisitor/Core/ValueSetter.cs)

    • -?[Gitee?ValueGetter](https://gitee.com/yks/Newbe.ObjectVisitor/blob/main/src/Newbe.ObjectVisitor/Newbe.ObjectVisitor/Core/ValueGetter.cs)

    • -?[Gitee?ValueSetter](https://gitee.com/yks/Newbe.ObjectVisitor/blob/main/src/Newbe.ObjectVisitor/Newbe.ObjectVisitor/Core/ValueSetter.cs)

    基準測試

    BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.572 (2004/?/20H1) Intel Xeon CPU E5-2678 v3 2.50GHz, 1 CPU, 24 logical and 12 physical cores .NET Core SDK=5.0.100-rc.2.20479.15[Host] : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJITnet461 : .NET Framework 4.8 (4.8.4250.0), X64 RyuJITnet48 : .NET Framework 4.8 (4.8.4250.0), X64 RyuJITnetcoreapp21 : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJITnetcoreapp31 : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJITnetcoreapp5 : .NET Core 5.0.0 (CoreCLR 5.0.20.47505, CoreFX 5.0.20.47505), X64 RyuJIT

    結論

  • 使用委托明顯比使用 PropertyInfo 要快,這個方案可以。

  • Framework 真拉胯,Net 5 簡直太強了。

  • 如果屬性是明確的,建議把字典中取出來的委托保存在自己的上下文,這可以明顯的省去查找的消耗。

  • 圖表

    從左往右分別是:直接讀取屬性、緩存委托、不緩存委托和使用 PropertyInfo。

    數據

    Getter

    MethodJobRuntimeMeanErrorStdDevMedianRatioRatioSDRank
    DirectlyStringnet461.NET 4.6.10.1636 ns0.0822 ns0.1126 ns0.1472 ns??2
    DirectlyIntnet461.NET 4.6.10.0318 ns0.0348 ns0.0342 ns0.0217 ns??1
    ReflectStringnet461.NET 4.6.1145.8375 ns2.2790 ns2.1317 ns145.6522 ns??7
    ReflectIntnet461.NET 4.6.1172.5066 ns1.3206 ns1.1028 ns172.6804 ns??8
    GetterStringnet461.NET 4.6.131.4379 ns0.6017 ns0.5334 ns31.6316 ns??4
    GetterIntnet461.NET 4.6.133.0642 ns0.4940 ns0.4380 ns33.0557 ns??5
    GetterObjectnet461.NET 4.6.133.9174 ns0.5587 ns0.5226 ns33.7326 ns??6
    GetterCachednet461.NET 4.6.17.5878 ns0.1223 ns0.1144 ns7.5765 ns??3










    DirectlyStringnet48.NET 4.80.0181 ns0.0353 ns0.0313 ns0.0043 ns??1
    DirectlyIntnet48.NET 4.80.0050 ns0.0089 ns0.0079 ns0.0000 ns??1
    ReflectStringnet48.NET 4.8143.8313 ns2.2501 ns2.1047 ns143.5568 ns??5
    ReflectIntnet48.NET 4.8172.1714 ns1.9819 ns1.7569 ns172.3142 ns??6
    GetterStringnet48.NET 4.831.5887 ns0.6310 ns0.5902 ns31.5385 ns??3
    GetterIntnet48.NET 4.832.7140 ns0.3992 ns0.3734 ns32.7343 ns??4
    GetterObjectnet48.NET 4.833.3063 ns0.2069 ns0.1834 ns33.3053 ns??4
    GetterCachednet48.NET 4.87.5540 ns0.2201 ns0.1951 ns7.5069 ns??2










    DirectlyStringnetcoreapp21.NET Core 2.10.0000 ns0.0000 ns0.0000 ns0.0000 ns??1
    DirectlyIntnetcoreapp21.NET Core 2.10.0193 ns0.0111 ns0.0104 ns0.0177 ns??2
    ReflectStringnetcoreapp21.NET Core 2.1110.4180 ns2.2159 ns1.8503 ns110.8038 ns??7
    ReflectIntnetcoreapp21.NET Core 2.1138.9612 ns0.9694 ns0.8594 ns138.8217 ns??8
    GetterStringnetcoreapp21.NET Core 2.116.8958 ns0.2384 ns0.2230 ns16.8103 ns??4
    GetterIntnetcoreapp21.NET Core 2.119.4407 ns0.2041 ns0.1809 ns19.4539 ns??6
    GetterObjectnetcoreapp21.NET Core 2.118.6922 ns0.2700 ns0.2255 ns18.6582 ns??5
    GetterCachednetcoreapp21.NET Core 2.10.9299 ns0.0457 ns0.0427 ns0.9308 ns??3










    DirectlyStringnetcoreapp31.NET Core 3.10.0000 ns0.0000 ns0.0000 ns0.0000 ns??1
    DirectlyIntnetcoreapp31.NET Core 3.10.0693 ns0.0102 ns0.0091 ns0.0709 ns??2
    ReflectStringnetcoreapp31.NET Core 3.198.6735 ns0.8335 ns0.7389 ns98.5319 ns??7
    ReflectIntnetcoreapp31.NET Core 3.1130.6941 ns0.9332 ns0.8730 ns130.5376 ns??8
    GetterStringnetcoreapp31.NET Core 3.114.8915 ns0.2025 ns0.1795 ns14.8911 ns??4
    GetterIntnetcoreapp31.NET Core 3.116.2874 ns0.0789 ns0.0700 ns16.2753 ns??5
    GetterObjectnetcoreapp31.NET Core 3.117.6202 ns0.1130 ns0.1057 ns17.6092 ns??6
    GetterCachednetcoreapp31.NET Core 3.10.6351 ns0.0244 ns0.0217 ns0.6393 ns??3










    DirectlyStringnetcoreapp5.NET Core 5.00.5098 ns0.0328 ns0.0291 ns0.5131 ns1.0000.002
    DirectlyIntnetcoreapp5.NET Core 5.00.0000 ns0.0000 ns0.0000 ns0.0000 ns0.0000.001
    ReflectStringnetcoreapp5.NET Core 5.088.8937 ns0.9697 ns0.8596 ns88.7457 ns174.8389.267
    ReflectIntnetcoreapp5.NET Core 5.0123.4464 ns1.0582 ns0.9898 ns123.3193 ns242.99614.008
    GetterStringnetcoreapp5.NET Core 5.07.6628 ns0.0931 ns0.0777 ns7.6703 ns15.0310.955
    GetterIntnetcoreapp5.NET Core 5.06.6645 ns0.0825 ns0.0772 ns6.6497 ns13.0850.694
    GetterObjectnetcoreapp5.NET Core 5.08.3090 ns0.1685 ns0.1576 ns8.2865 ns16.3440.836
    GetterCachednetcoreapp5.NET Core 5.00.9791 ns0.0293 ns0.0245 ns0.9764 ns1.9200.133

    Setter

    MethodJobRuntimeMeanErrorStdDevMedianRatioRatioSDRank
    DirectlyStringnet461.NET 4.6.12.0161 ns0.0300 ns0.0266 ns2.0045 ns1.0000.002
    DirectlyIntnet461.NET 4.6.10.0076 ns0.0094 ns0.0083 ns0.0081 ns0.0040.001
    ReflectStringnet461.NET 4.6.1237.5006 ns4.5706 ns4.4890 ns236.5912 ns117.8713.405
    ReflectIntnet461.NET 4.6.1249.3627 ns2.1717 ns2.0314 ns249.0283 ns123.6811.946
    GetterStringnet461.NET 4.6.132.8621 ns0.2855 ns0.2229 ns32.9189 ns16.3350.224
    GetterIntnet461.NET 4.6.133.6103 ns0.4245 ns0.3544 ns33.5499 ns16.6950.264
    GetterObjectnet461.NET 4.6.133.2561 ns0.2966 ns0.2629 ns33.1795 ns16.4970.174
    GetterCachednet461.NET 4.6.19.1805 ns0.0761 ns0.0674 ns9.1802 ns4.5540.083










    DirectlyStringnet48.NET 4.81.9272 ns0.0298 ns0.0264 ns1.9245 ns1.0000.002
    DirectlyIntnet48.NET 4.80.0000 ns0.0000 ns0.0000 ns0.0000 ns0.0000.001
    ReflectStringnet48.NET 4.8237.7686 ns4.6597 ns5.3661 ns235.8445 ns123.9083.575
    ReflectIntnet48.NET 4.8249.6291 ns4.5333 ns4.2404 ns249.5459 ns129.6893.136
    GetterStringnet48.NET 4.832.2366 ns0.1941 ns0.1721 ns32.1780 ns16.7310.294
    GetterIntnet48.NET 4.832.0081 ns0.1488 ns0.1162 ns32.0270 ns16.5720.234
    GetterObjectnet48.NET 4.832.6413 ns0.1417 ns0.1183 ns32.6260 ns16.9070.244
    GetterCachednet48.NET 4.89.2589 ns0.0928 ns0.0868 ns9.2564 ns4.7990.073










    DirectlyStringnetcoreapp21.NET Core 2.12.4107 ns0.0507 ns0.0475 ns2.3936 ns1.0000.002
    DirectlyIntnetcoreapp21.NET Core 2.10.0007 ns0.0028 ns0.0025 ns0.0000 ns0.0000.001
    ReflectStringnetcoreapp21.NET Core 2.1203.6637 ns3.6109 ns3.3777 ns203.4793 ns84.5172.317
    ReflectIntnetcoreapp21.NET Core 2.1213.8619 ns2.1882 ns1.9398 ns213.7367 ns88.7571.718
    GetterStringnetcoreapp21.NET Core 2.119.5240 ns0.0811 ns0.0758 ns19.5149 ns8.1020.155
    GetterIntnetcoreapp21.NET Core 2.118.8794 ns0.1193 ns0.1058 ns18.8837 ns7.8360.184
    GetterObjectnetcoreapp21.NET Core 2.120.6765 ns0.2709 ns0.2115 ns20.6419 ns8.5840.146
    GetterCachednetcoreapp21.NET Core 2.12.7606 ns0.0613 ns0.0512 ns2.7590 ns1.1480.023










    DirectlyStringnetcoreapp31.NET Core 3.12.2625 ns0.0647 ns0.0605 ns2.2555 ns1.0000.002
    DirectlyIntnetcoreapp31.NET Core 3.10.0072 ns0.0165 ns0.0146 ns0.0000 ns0.0030.011
    ReflectStringnetcoreapp31.NET Core 3.1182.7306 ns3.3249 ns3.1101 ns182.3062 ns80.8041.997
    ReflectIntnetcoreapp31.NET Core 3.1192.2510 ns2.3691 ns2.1002 ns191.4821 ns85.0612.888
    GetterStringnetcoreapp31.NET Core 3.116.9918 ns0.2115 ns0.1979 ns16.9651 ns7.5160.255
    GetterIntnetcoreapp31.NET Core 3.116.1168 ns0.3558 ns0.3654 ns15.9822 ns7.1380.194
    GetterObjectnetcoreapp31.NET Core 3.119.3060 ns0.4173 ns0.5571 ns19.4856 ns8.4800.456
    GetterCachednetcoreapp31.NET Core 3.12.9276 ns0.0156 ns0.0146 ns2.9313 ns1.2950.033










    DirectlyStringnetcoreapp5.NET Core 5.02.2455 ns0.0084 ns0.0078 ns2.2460 ns1.0000.002
    DirectlyIntnetcoreapp5.NET Core 5.00.0000 ns0.0000 ns0.0000 ns0.0000 ns0.0000.001
    ReflectStringnetcoreapp5.NET Core 5.0162.8780 ns0.7135 ns0.6674 ns162.8741 ns72.5380.457
    ReflectIntnetcoreapp5.NET Core 5.0171.1380 ns0.4173 ns0.3699 ns171.1414 ns76.2170.318
    GetterStringnetcoreapp5.NET Core 5.08.6244 ns0.1891 ns0.1769 ns8.5469 ns3.8410.085
    GetterIntnetcoreapp5.NET Core 5.06.5511 ns0.0347 ns0.0325 ns6.5634 ns2.9170.024
    GetterObjectnetcoreapp5.NET Core 5.09.0732 ns0.0306 ns0.0272 ns9.0735 ns4.0410.026
    GetterCachednetcoreapp5.NET Core 5.02.8223 ns0.0728 ns0.0681 ns2.8190 ns1.2570.033

    總結

    使用表達式創建委托來取代 PropertyInfo 讀取和寫入屬性效果很好。

    開發者也可以直接引用 Newbe.ObjectVisitor 包來使用已經封裝好的 ValueGetter 和 ValueSetter。

    我只是知識的搬運工

    -?[晚綁定場景下對象屬性賦值和取值可以不需要?PropertyInfo](https://www.cnblogs.com/artech/archive/2011/03/24/PropertyAccessor.html)

    -?[三種屬性操作性能比較:PropertyInfo?+?Expression?Tree?+?Delegate.CreateDelegate](https://www.cnblogs.com/artech/archive/2011/03/26/Propertyaccesstest.html)

    -?[關于?Expression?Tree?和?IL?Emit?的所謂的"性能差別"](https://www.cnblogs.com/artech/archive/2011/03/27/ExpressTreeVsIlEmit.html)

    總結

    以上是生活随笔為你收集整理的寻找性能更优秀的动态 Getter 和 Setter 方案的全部內容,希望文章能夠幫你解決所遇到的問題。

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