[.Net concept]使用方法與屬性時適時為其值做快取


這是一個很簡單的小概念,沒甚麼難度,但卻常被開發人員忽略。這很概念理解並養成習慣後,能默默的為程式帶向較好的效能,避免在不自覺中踩中地雷,讓後續效能調校時要花更多的功夫,這邊筆者稍微的帶一下~順手紀錄一下。



假使今天我們在撰寫的函式中,要用到某道函式,假設其函式名為Count,可用來取得資料個數,在使用不止一次且預期每次得到相同值的情況下,建議為其值做快取,並以該快取值做後續的處理。像是類似下面這樣的程式:



static void Main(string[] args)
{
for (int i = 0; i < Count(); ++i)
{
for (int j = 0; j < Count(); ++j)

}
}



應該將它改為類似下面這樣:



static void Main(string[] args)
{
int count = Count();
for (int i = 0; i < count; ++i)
{
for (int j = 0; j < count; ++j)

}
}



會這樣建議是因為我們無法從函式名稱中有效的掌握用到的函式內部做了甚麼處理,其內部的實現可能特別耗時,像是下面這樣:



static int Count()
{
int count;

//Calculate count....
...

return count;

}



多次的叫用會讓整個程式效能耗費因此而下降,且這些都是不必要的花費。就算在函式的內部實現中已做了快取,仍是無法避免函式叫用所衍生的Push參數、區域變數、返回位置等基本耗費,也無法避免內部實現會隨著需求變化突然變得耗時。



若是能適時的將其值快取,後續的使用都是透過用來快取的變數,就不用再次叫用函式,也不會引發一連串的問題。



相同的道理在屬性值的取用上也適用,因為屬性在底層的實現是由get與set兩道函式所組成(可參閱筆者撰寫的[C#]Effective C# 條款一: 使用屬性代替公有欄位),不僅也會有函式叫用基本的耗費,一樣的我們也無法從屬性名稱就清楚的掌握到底層的實現,到底在屬性值傳回前內部做了甚麼樣的處理,是不是特別的耗時。



static void Main(string[] args)
{
MyClass myObj = new MyClass();

int count = myObj.Count;
for (int i = 0; i &lt; count; ++i)
{ 
    for (int j = 0; j &lt; count; ++j)
    ...
}

}



Link



  • C# Property Performance


  • How to Write High-Performance C# Code