string是不變類,使用+操作連線字串會導致建立乙個新的字串。如果字串連線次數不是固定的,例如在乙個迴圈操作中,則應該使用stringbuilder類來做字串連線工作。因為stringbuilder內部有乙個stringbuffer,連線字元操作不會每次分配新的字串空間。只有當連線後的字串超出buffer大小是,才會申請信的buffer空間。典型**如下:
stringbuiler sb = new stringbuilder(256);
for(int i = 0; i < str.count; i++)
而如果連線字元數十固定的並且只有幾次,此時應該直接用+號連線,保持程式簡潔易讀。實際上,編譯器已經做了優化,會依據加號次數呼叫不同引數個數的string.concat方法。例如:
string str = str1 + str2 + str3 + str4;
會被編譯成:sting.concat(str1,str2,str3,str4).該方法內部會計算總的string長度,僅分配一次,並不會如通常想象的那樣分配三次。作為乙個值,當字串連線操作達到10此以上時,則應該使用stringbuilder.
這裡有個細節要注意:stringbuilder內部buffer的預設值為16,這個實在太小。按照stingbuilder的使用場景,buffer肯定得重新分配。我建議使用256作為buffer的初值。當然,如果能計算出最終生成字串長度的話,則應該按這個值來設定buffer的初值。我曾經開發過乙個44位的uuid生成方法,僅僅把new stringbuilder()改為stringbuilder(44)前後就有3倍的效率差異。
string是不變類,呼叫toupper或tolower方法都會導致建立乙個新字串。如果被頻繁呼叫,將導致頻繁建立字串物件。這違背了前面講到的「避免頻繁建立物件」這一基本原則。
例如,bool.parse方法本身已經是忽略大小寫的,但下面的**每次訪問isnullable屬性時,都要不必要的呼叫tolower方法:
publicvirtual
bool isnullable}}
}
另外乙個非常鋪平的場景是字串比較,例如:
foreach (xmlnode node in documentelement.childnodes)else
if (node.name.tolower() == "render")
else
if (node.name.tolower() == "render")}}
高效的做法是使用compare方法,這個方法可以做大小寫忽略的比較,並且不會建立新字串:
最後列舉的乙個示例是使用hashtable的時候,有時候無法保證傳遞key的大小寫是否符合預期,往往會把key強制轉換到大小寫方式,例如:mytalbe.add(mykey.tolower(),myobject).實際上hashtable有不同的構造方式,完全支援採用忽略大小寫的key:new hashtable(stringcomparer.ordinalignorecase).
將string物件的length屬性與0比較式最快的方法:if(str.length == 0)
其次是與sting.empty常量或空串比較;if(str == string.empty)或if(str == "")
注:c#在編譯時會將程式集中宣告的所有字串常量放到保留池中(intern pool),相同常量不會重複分配。
《軟體開發效能優化系列》之String操作
string是不變類,使用 操作連線字串會導致建立乙個新的字串。如果字串連線次數不是固定的,例如在乙個迴圈操作中,則應該使用stringbuilder類來做字串連線工作。因為stringbuilder內部有乙個stringbuffer,連線字元操作不會每次分配新的字串空間。只有當連線後的字串超出bu...
《軟體開發效能優化系列》之表設計
樹狀表都是使用id和idparent兩個欄位來表示樹關係。對樹進行查詢只能使用自關聯方式,不光寫法麻煩而且記錄多的時候查詢效能會非常差。建議在設計樹表的時候可以考慮加入treepath欄位,記載到該節點記錄需要經歷的樹路徑。雖然會增加insert和update的成本。但是對查詢樹關係非常有幫助。可以...
《軟體開發效能優化系列》之Sql效能優化 一
對於一般簡單查詢,資料庫能自動引數啊以重用計畫快取,如 select from table where id 1 select from table where id 4 在sqlserver內部能自動引數化這個查詢,select from table where id 1 但是一旦sql語句中帶有...