最近在跟同事討論如何改寫舊專案,其中討論到使用 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 了~