【C#】Reflection 取 Enum Description vs Dictionary[key] 效能比較

最近在跟同事討論如何改寫舊專案,其中討論到使用 Enum 來管理 Cache Key,除了避免打錯字的問題以外,也防範不小心剛好跟其他同仁取到同樣的 key 名稱而導致程式出問題的狀況。

讓我猶豫的關鍵是我們需要取得 Enum 的 Description,而就我所知這需使用到 Reflection,而以前吃過 Reflection 效能的虧,所以決定測一下以保心安。

public static class EnumExtension
{
    public static string GetDescription(this Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

        if (attributes != null && attributes.Any())
        {
            return attributes.First().Description;
        }

        return value.ToString();
    }
}

private enum Book
{
    [Description("死神小學生的故事")] 
    DetectiveConan
}

public static void Main(string[] args)
{
    Dictionary<Book, string> dictionary = new Dictionary<Book, string>()
    {
        { Book.DetectiveConan, "死神小學生的故事" }
    };

    int loopNum = 1;
    Stopwatch sw = Stopwatch.StartNew();
    for (int i = 0; i < loopNum; i++)
    {
        string description = dictionary[Book.DetectiveConan];
    }
    sw.Stop();
    Console.WriteLine($"dictionary[key]:{sw.ElapsedMilliseconds}ms");
    
    sw.Restart();
    for (int i = 0; i < loopNum; i++)
    {
        string description = Book.DetectiveConan.GetDescription();
    }
    sw.Stop();
    Console.WriteLine($"Reflection:{sw.ElapsedMilliseconds}ms");
}
//取1次資料的result
dictionary[key]:0ms
Reflection:3ms
//取500次資料的result
dictionary[key]:0ms
Reflection:4ms
//取5000次資料的result
dictionary[key]:0ms
Reflection:11ms
//取50000次資料的result
dictionary[key]:0ms
Reflection:70ms
//取100000次資料的result
dictionary[key]:1ms
Reflection:150ms
//取800000次資料的result
dictionary[key]:5ms
Reflection:1095ms

看起來80萬次左右才會有到一秒的差距,看來也不需要避 Reflection 如蛇蠍,只需要在使用的時候評估使用頻率,就可以安心使用 Reflection 了~

分類: C#

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *