最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# 泛型編譯特性對性能的影響小結(jié)

 更新時(shí)間:2023年11月29日 14:37:27   作者:編寫人生  
C#作為一種強(qiáng)類型語言,具有豐富的泛型支持,允許開發(fā)者編寫可以應(yīng)對不同數(shù)據(jù)類型的通用代碼,這篇文章主要介紹了C# 泛型編譯特性對性能的影響 ,需要的朋友可以參考下

C#作為一種強(qiáng)類型語言,具有豐富的泛型支持,允許開發(fā)者編寫可以應(yīng)對不同數(shù)據(jù)類型的通用代碼。然而,在泛型編譯時(shí),針對結(jié)構(gòu)和類作為泛型參數(shù)時(shí),會對性能產(chǎn)生不同的影響。

泛型編譯行為

在C#中,泛型編譯行為取決于泛型參數(shù)的類型。具體而言,當(dāng)泛型參數(shù)是結(jié)構(gòu)(Struct)時(shí),編譯器會針對每個(gè)具體的結(jié)構(gòu)類型生成特定的實(shí)現(xiàn)。而當(dāng)泛型參數(shù)是類(Class)時(shí),編譯器則可能生成更通用的實(shí)現(xiàn)。

結(jié)構(gòu) vs 類

結(jié)構(gòu)(Struct)

結(jié)構(gòu)是值類型,它們存儲在棧上,具有較小的內(nèi)存開銷。當(dāng)泛型參數(shù)是結(jié)構(gòu)時(shí),編譯器會針對每個(gè)具體的結(jié)構(gòu)類型生成專門的實(shí)現(xiàn),這可能導(dǎo)致更高的性能。因?yàn)槊總€(gè)結(jié)構(gòu)類型都有自己的實(shí)現(xiàn),避免了裝箱和拆箱的開銷,同時(shí)優(yōu)化了內(nèi)存分配和訪問。

類(Class)

類是引用類型,存儲在堆上,需要通過引用進(jìn)行訪問。當(dāng)泛型參數(shù)是類時(shí),編譯器可能生成更通用的實(shí)現(xiàn)。這可能導(dǎo)致較低的性能,因?yàn)橥ㄓ脤?shí)現(xiàn)需要進(jìn)行動態(tài)調(diào)度和引用類型的操作,增加了一些開銷。

測試性能差異

針對不同的泛型參數(shù)進(jìn)行性能測試是一種有效的方法,以觀察結(jié)構(gòu)和類對泛型編譯特性的影響。在測試中,可能會發(fā)現(xiàn)對結(jié)構(gòu)類型的泛型參數(shù),其性能可能更高,而對類類型的泛型參數(shù),其性能可能略低。

using System.Diagnostics;
namespace ConsoleApp1 {
    internal interface IValueGetter {
        int GetValue(int index);
    }
    internal class MyTestClass<T> where T : IValueGetter {
        private readonly T _valueGetter;
        public MyTestClass(T valueGetter) {
            _valueGetter = valueGetter;
        }
        public void Run() {
            long r = 0L;
            for (int i = 0; i < int.MaxValue; i++) {
                r += _valueGetter.GetValue(i);
            }
        }
    }
    internal struct StructValueGetter : IValueGetter {
        public readonly int GetValue(int index) {
            return index + 3;
        }
    }
    internal struct StructValueGetter2(int someField) : IValueGetter {
        public readonly int GetValue(int index) {
            return index + 5;
        }
    }
    internal class ClassValueGetter1 : IValueGetter {
        public int GetValue(int index) {
            return index + 5;
        }
    }
    internal class ClassValueGetter2 : IValueGetter {
        public int GetValue(int index) {
            return index + 7;
        }
    }
    internal static class Demo2 {
        public static  void Run() {
            var t1 = new MyTestClass<StructValueGetter>(new StructValueGetter());
            RunDemo("StructValueGetter ", t1.Run);
            var t2 = new MyTestClass<ClassValueGetter1>(new ClassValueGetter1());
            RunDemo("ClassValueGetter1 ", t2.Run);
            var t3 = new MyTestClass<ClassValueGetter2>(new ClassValueGetter2());
            RunDemo("ClassValueGetter2 ", t3.Run);
            var t4 = new MyTestClass<IValueGetter>(new ClassValueGetter1());
            RunDemo("IValueGetter-1    ", t4.Run);
            var t5 = new MyTestClass<ClassValueGetter1>(new ClassValueGetter1());
            RunDemo("ClassValueGetter1 ", t5.Run);
            var t6 = new MyTestClass<StructValueGetter2>(new StructValueGetter2());
            RunDemo("StructValueGetter2", t6.Run);
            var t7 = new MyTestClass<IValueGetter>(new ClassValueGetter2());
            RunDemo("IValueGetter-2    ", t7.Run);
            var t8 = new MyTestClass<IValueGetter>(new StructValueGetter());
            RunDemo("IValueGetter-3    ", t8.Run);
            var t9 = Activator.CreateInstance(typeof(MyTestClass<>).MakeGenericType(typeof(StructValueGetter)), new StructValueGetter());
            Action action9 = (Action)Delegate.CreateDelegate(typeof(Action), t9, t9.GetType().GetMethod("Run"));
            RunDemo("Dynamic-Struct    ", action9);
        }
        static void RunDemo(string caption, Action action) {
            var stopWatch = Stopwatch.StartNew();
            action();
            stopWatch.Stop();
            Console.WriteLine($"{caption} time = {stopWatch.Elapsed}");
        }
    }
}
Demo2.Run();

在.net 8.0 Release 編譯執(zhí)行的參考結(jié)果如下:

StructValueGetter  time = 00:00:00.6920186
ClassValueGetter1  time = 00:00:01.1887137
ClassValueGetter2  time = 00:00:05.2889692
IValueGetter-1     time = 00:00:01.1652195
ClassValueGetter1  time = 00:00:01.1625259
StructValueGetter2 time = 00:00:00.6488674
IValueGetter-2     time = 00:00:05.2114724
IValueGetter-3     time = 00:00:07.1394676
Dynamic-Struct     time = 00:00:00.6491220

結(jié)論

泛型編譯特性對性能有所影響,我們發(fā)現(xiàn):

  • 泛型參數(shù)是 Struct 比 class 的性能要好,大約有兩倍的差異;
  • 泛型參數(shù)如果存在多個(gè) Struct 可能時(shí),性能沒有影響,但如果泛型參數(shù)存在多個(gè) class 可能時(shí),性能急劇下降5倍之多;
  • 泛型參數(shù)如果是接口形式,無論實(shí)際填充的結(jié)構(gòu)還是類,其最終的執(zhí)行性能一定是很慢的;
  • 使用反射(例如:MakeGenericType)構(gòu)建出的泛型實(shí)例,其實(shí)際運(yùn)行性能并不受影響,非常適合高度定制的運(yùn)行時(shí)類型構(gòu)建,這一點(diǎn)非常重要,例如你可以在運(yùn)行時(shí)檢測實(shí)際情況,構(gòu)建出不同的比較器對象,雖然構(gòu)建的工廠方法返回的是接口,但你可以使用反射的方式動態(tài)傳入字典的比較器參數(shù)(實(shí)際上c#的 Dictionary<TKey, TValue> 這點(diǎn)設(shè)計(jì)是失敗的,他的comparer不是一個(gè)泛型參數(shù),而是接口);

綜上所述,了解C#泛型編譯特性對性能的影響是編寫高性能代碼的重要一部分,合理使用對于關(guān)鍵性代碼性能至關(guān)重要。

到此這篇關(guān)于C# 泛型編譯特性對性能的影響 的文章就介紹到這了,更多相關(guān)C# 泛型編譯特性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中Dictionary的作用及用法講解

    C#中Dictionary的作用及用法講解

    這篇文章主要介紹了C#中Dictionary的作用及用法講解,本文還對dictionary類用什么接口實(shí)現(xiàn)、Dictionary的基本用法做了講解,需要的朋友可以參考下
    2014-10-10
  • C#簡單實(shí)現(xiàn)IOC容器的示例代碼

    C#簡單實(shí)現(xiàn)IOC容器的示例代碼

    IoC 的原理是通過將對象的創(chuàng)建和依賴關(guān)系的管理交給外部容器來實(shí)現(xiàn),從而降低了代碼的耦合度,提高了代碼的可維護(hù)性和可測試性,下面我們就來看看如何通過C#實(shí)現(xiàn)一個(gè)IOC容器吧
    2024-02-02
  • 基于C#實(shí)現(xiàn)微信支付寶掃碼支付功能

    基于C#實(shí)現(xiàn)微信支付寶掃碼支付功能

    為公司系統(tǒng)業(yè)務(wù)需要,這幾天了解了一下微信和支付寶掃碼支付的接口,并用c#實(shí)現(xiàn)了微信和支付寶掃碼支付的功能。需要的朋友跟隨小編一起看看吧
    2019-06-06
  • C#編寫控制臺程序紙牌游戲

    C#編寫控制臺程序紙牌游戲

    這篇文章主要為大家詳細(xì)介紹了C#編寫控制臺程序紙牌游戲,適合C#初學(xué)者,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • C#使用List類實(shí)現(xiàn)動態(tài)變長數(shù)組的方法

    C#使用List類實(shí)現(xiàn)動態(tài)變長數(shù)組的方法

    這篇文章主要介紹了C#使用List類實(shí)現(xiàn)動態(tài)變長數(shù)組的方法,涉及C#中List類的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#中Hashtable和Dictionary的區(qū)別

    C#中Hashtable和Dictionary的區(qū)別

    Hashtable 和 Dictionary 都是 C# 中用于存儲鍵值對的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了C#中Hashtable和Dictionary的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • C#怎樣才能實(shí)現(xiàn)窗體最小化到托盤呢?

    C#怎樣才能實(shí)現(xiàn)窗體最小化到托盤呢?

    C#怎樣才能實(shí)現(xiàn)窗體最小化到托盤呢?...
    2007-03-03
  • c#實(shí)現(xiàn)漢諾塔問題示例

    c#實(shí)現(xiàn)漢諾塔問題示例

    這篇文章主要介紹了c#實(shí)現(xiàn)漢諾塔問題示例,需要的朋友可以參考下
    2014-04-04
  • C#下Newtonsoft.Json的具體使用

    C#下Newtonsoft.Json的具體使用

    Newtonsoft.Json是一個(gè)非常流行的C# JSON 序列化和反序列化庫,它可以方便地將C#對象轉(zhuǎn)換為JSON 格式,或者將 JSON 數(shù)據(jù)解析為 C# 對象,下面就來介紹一下具體使用
    2025-07-07
  • C#結(jié)合OpenCVSharp4實(shí)現(xiàn)圖片相似度識別

    C#結(jié)合OpenCVSharp4實(shí)現(xiàn)圖片相似度識別

    這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合OpenCVSharp4實(shí)現(xiàn)圖片相似度識別,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-09-09

最新評論

怀远县| 普定县| 韶山市| 阿拉善右旗| 禄劝| 阿城市| 临江市| 东港市| 陈巴尔虎旗| 济宁市| 正安县| 高密市| 上虞市| 昌平区| 深水埗区| 天津市| 若羌县| 澄城县| 蒲江县| 韶关市| 浦江县| 焉耆| 紫阳县| 简阳市| 上犹县| 凉城县| 隆回县| 鄂温| 三台县| 正镶白旗| 新绛县| 梁山县| 乐亭县| 建阳市| 仪陇县| 方山县| 鄢陵县| 仁布县| 青冈县| 台中市| 铁力市|